使用async/await时,如何在Win Forms构造函数中修复此死锁?

Joh*_*zen -1 .net c# deadlock task-parallel-library async-await

这是我的最低代表案例:

public Form1()
{
    Task.Delay(100).Wait();  // Works just fine

    this.Await().Wait();     // Blocks indefinitely
}

private async Task Await()
{
    await Task.Delay(100);
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么这两个表现不一样?我该怎么做才能使后一个工作?

我的实际案例不那么简单,我不能"只使用第一个选项".

Ste*_*ary 5

您将看到我在博客MSDN文章中描述的典型死锁情况.简而言之,在await完成之后,该async方法尝试在您通过调用阻止的UI线程上恢复Wait.

要修复它,理想情况下你想要一直使用async(即永远不会阻塞async代码).构造者在这里构成了一个困难(因为它们不可能async); 我在博客上探索了几个选项.正确的选项取决于您的代码库,但async如果可能,我建议使用工厂方法.选项是:

  • 异步工厂方法.
  • 异步延迟初始化.
  • 异步初始化模式.

如果你绝对不能使用我在博客上描述的其中一个选项,那么你可以通过ConfigureAwait(false)在所有async方法中使用来解决这个问题,然后你Wait()就不会陷入僵局.但是,这在这些异步方法调用期间阻塞UI线程(这种方式会破坏它们async首先出现的目的......)