异步等待停止... C# WPF
Async Await Stops... C# WPF
我有一个函数,它获取一个 Func 作为参数,并以异步方法在任务内部执行它,以便在函数运行时显示不确定的进度条....
private async void Invoke(Func<string> function)
{
if(calculation?.Status == TaskStatus.Running) await calculation;
calculation = Task.Run(function);
InvokeA(() => prg.Height = double.NaN);
InvokeA(() => prg.Visibility = Visibility.Visible);
Result = await calculation;
InvokeA(() => prg.Visibility = Visibility.Hidden);
InvokeA(() => prg.Height = 0);
}
问题是函数何时达到:
Result = await Calculation;
它有点停止...它永远不会真正设置值或关闭进度条。
如果键为 Enter,则从 Textbox.KeyDown 方法调用调用:
if (SpecialCommands.DoesExist(Text))
{
Invoke(() => SpecialCommands.Invoke(Parameter));
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
}
变量定义:
calculation = Task<string>
Result = string
prg = ProgressBar
Parameter = string that isn't connected to the UI
我使用以下内容创建了一个标准的新 WPF 应用程序项目XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Button x:Name="button" Content="Button" Canvas.Left="62" Canvas.Top="40" Width="75" Click="button_Click"/>
<ProgressBar x:Name="prg" Height="23" Canvas.Left="62" Canvas.Top="265" Width="347" IsIndeterminate="True"/>
</Canvas>
</Window>
和代码隐藏
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Task<string> calculation;
string Result;
string Text;
private async void button_Click(object sender, RoutedEventArgs e)
{
await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
}
private async Task Invoke(Func<string> function)
{
if (calculation?.Status == TaskStatus.Running) await calculation;
calculation = Task.Run(function);
InvokeA(() => prg.Height = double.NaN);
InvokeA(() => prg.Visibility = Visibility.Visible);
Result = await calculation;
InvokeA(() => prg.Visibility = Visibility.Hidden);
InvokeA(() => prg.Height = 0);
}
private void InvokeA(Action a) { a(); }
static string Foo()
{
Thread.Sleep(5000);
return "Bar";
}
}
它按预期工作。所以问题出在您提供的其他地方。
EDIT 根据您的评论,值得尝试以下操作,因为那是您代码的错误部分:
首先,将Invoke
方法的签名改为
private async Task Invoke(Func<string> function)
然后使用
await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
希望对您有所帮助。
我有一个函数,它获取一个 Func 作为参数,并以异步方法在任务内部执行它,以便在函数运行时显示不确定的进度条....
private async void Invoke(Func<string> function)
{
if(calculation?.Status == TaskStatus.Running) await calculation;
calculation = Task.Run(function);
InvokeA(() => prg.Height = double.NaN);
InvokeA(() => prg.Visibility = Visibility.Visible);
Result = await calculation;
InvokeA(() => prg.Visibility = Visibility.Hidden);
InvokeA(() => prg.Height = 0);
}
问题是函数何时达到:
Result = await Calculation;
它有点停止...它永远不会真正设置值或关闭进度条。
如果键为 Enter,则从 Textbox.KeyDown 方法调用调用:
if (SpecialCommands.DoesExist(Text))
{
Invoke(() => SpecialCommands.Invoke(Parameter));
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
}
变量定义:
calculation = Task<string>
Result = string
prg = ProgressBar
Parameter = string that isn't connected to the UI
我使用以下内容创建了一个标准的新 WPF 应用程序项目XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Button x:Name="button" Content="Button" Canvas.Left="62" Canvas.Top="40" Width="75" Click="button_Click"/>
<ProgressBar x:Name="prg" Height="23" Canvas.Left="62" Canvas.Top="265" Width="347" IsIndeterminate="True"/>
</Canvas>
</Window>
和代码隐藏
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Task<string> calculation;
string Result;
string Text;
private async void button_Click(object sender, RoutedEventArgs e)
{
await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
}
private async Task Invoke(Func<string> function)
{
if (calculation?.Status == TaskStatus.Running) await calculation;
calculation = Task.Run(function);
InvokeA(() => prg.Height = double.NaN);
InvokeA(() => prg.Visibility = Visibility.Visible);
Result = await calculation;
InvokeA(() => prg.Visibility = Visibility.Hidden);
InvokeA(() => prg.Height = 0);
}
private void InvokeA(Action a) { a(); }
static string Foo()
{
Thread.Sleep(5000);
return "Bar";
}
}
它按预期工作。所以问题出在您提供的其他地方。
EDIT 根据您的评论,值得尝试以下操作,因为那是您代码的错误部分:
首先,将Invoke
方法的签名改为
private async Task Invoke(Func<string> function)
然后使用
await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $" ---> {Result}";
希望对您有所帮助。