当我使用Console.WriteLine打印异步方法的结果时,为什么这段代码会挂起?

时间:2016-06-18 08:50:29

标签: c# wpf c#-5.0

这是我的WPF代码。

public partial class MainWindow : Window
{
    delegate Task<int> testasync();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        testasync atest = new testasync(async () => { var result = await Thread_sleep(); return result; });
        System.Console.WriteLine("begin");
        System.Console.WriteLine("1");
        System.Console.WriteLine(atest().Result);
        System.Console.WriteLine("3");
    }

    async public Task<int> Thread_sleep()
    {
        await Task.Delay(10);
        return 2;
    }
}

我希望结果是1,3,2,但它会挂起。但是,当我使用Thread_sleep方法打印&#39; 2&#39;时,它可以正常工作。

1 个答案:

答案 0 :(得分:1)

atest().Result是一个同步调用,导致死锁(await Task.Delay(10)的延续尝试在UI线程上运行,被您的调用阻止)。

两种可能的修复方法:

  1. (首选解决方案)等待结果,而不是使用Result属性:

    var result = await atest();
    System.Console.WriteLine(result);
    
  2. 更改异步调用,以便不在UI线程上运行continuation:

    await Task.Delay(10).ConfigureAwait(false);
    

    var result = await Thread_sleep().ConfigureAwait(false);
    
  3. 根据经验,永远不要在WPF应用程序中的任务上使用.Result.Wait(),除非您完全确定需要。请务必尝试使用await