在WPF应用程序中而不是在控制台应用程序中具有死锁的异步计算

时间:2018-09-19 09:26:45

标签: c# async-await

我试图重现带有死锁的情况,如本例所示:

  

https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

这是我在控制台应用程序中运行的代码:

class Program
{
    static async Task<int> f()
    {
        var t = Task.Delay(1000);  //and not Task.Delay(1000).ConfigureAwait(false);
        await t;
        return 1; // line execute in a woker thread
    }
    static async Task g()
    {
        int p=await f();
    }

    static void Main(string[] args)
    {
        var t=g(); //0
        t.Wait();
    }
}

此代码不会阻止:尽管我还没有写Task.Delay(1000).ConfigureAwait(false);

,但返回1是在另一个线程中执行的示例。

但是正如我所预见的,这个wpf应用程序有一个死锁:

<Application x:Class="WpfApplication3.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WpfApplication3"
         Startup="Application_Startup">
<Application.Resources>

</Application.Resources>

    public partial class App : Application
{


    public async Task<int> f()
    {

        var t = Task.Delay(1000)
        await t;
        return 1;
    }
    public async Task g()
    {
        int p = await f();
        a = 1 + p;
    }
    private void Application_Startup(object sender, StartupEventArgs e)
    {

        var t = g();
        t.Wait();

    }
}

我不明白为什么控制台应用程序没有死锁,而wpf应用程序却有死锁。

谢谢您的帮助

1 个答案:

答案 0 :(得分:2)

来自https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/

SynchronizationContext.Current在控制台应用程序中为null,因此避免了Stephen Cleary在帖子中描述的僵局。