异步等待停止。。。C#WPF

异步等待停止。。。C#WPF,c#,wpf,asynchronous,task,C#,Wpf,Asynchronous,Task,我有一个函数,它获取一个Func作为参数,并以异步方法在任务内部执行它,以便在函数运行时显示不确定的进度条 private async void Invoke(Func<string> function) { if(calculation?.Status == TaskStatus.Running) await calculation; calculation = Task.Run(function); InvokeA(() => pr

我有一个函数,它获取一个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);
}
它停止了。。。它永远无法实际设置值或关闭进度条

如果键为Enter,则从Textbox.KeyDown方法调用Invoke:

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
计算=任务
结果=字符串
prg=进度条
参数=未连接到UI的字符串

我用以下XAML创建了一个标准的新WPF应用程序项目

<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>
然后使用

await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $"   --->   {Result}";

希望对您有所帮助。

搜索“异步任务.在GUI线程上运行”,您将找到死锁的原因。
计算设置在哪里,它的类型是什么?通常,您会在实际调用
async
方法时使用
await
关键字。请提供示例代码来演示问题,而不是感谢注释(已删除)。到目前为止显示的代码应该可以工作。另外,请确保在“it just stops”时显示一堆有趣的广告,并在更新帖子时查看关于“C#async Wait deadlock”的类似帖子。旁注:“crash”和“stops”在谈论程序时通常是不同的。“停止”的同义词是“冻结”;“崩溃”通常意味着异常/终止。@JamesWright计算是一项任务,结果是一个字符串在调试和更改某些内容后,我仍然有问题,但现在我看到调用方法被执行,调用后的行没有被执行<代码>调用(()=>Foo())如果(!string.IsNullOrEmpty(Result))Text+=$“-->{Result}”,则执行此操作这不是,那是因为
结果
为null或空!事实并非如此,我不是说
文本
没有改变,我是说调试器只是跳过了
的整行,如果
,它甚至没有检查它……那么我就没有更多的想法了。正如您可能已经看到的,我的两个测试样本都有效。祝你好运实际上,我试着像你在编辑中那样更改方法签名,现在一切都正常了。。。
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";
    }
}
private async Task Invoke(Func<string> function)
await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $"   --->   {Result}";