这是我的最低代表案例:
public Form1()
{
Task.Delay(100).Wait(); // Works just fine
this.Await().Wait(); // Blocks indefinitely
}
private async Task Await()
{
await Task.Delay(100);
}
这里发生了什么?为什么这两个表现不一样?我该怎么做才能使后一个工作?
我的实际案例不那么简单,我不能“只使用第一个选项”。
答案 0 :(得分:5)
您看到了我描述on my blog和in an MSDN article的典型死锁情况。简而言之,在await
完成后,async
方法尝试在UI线程上恢复,您已通过调用Wait
来阻止该线程。
要解决此问题,您最好一直使用async
(即永远不要阻止async
代码)。构造函数在这里构成了一个难点(因为它们不能是async
);我探索了几个选项on my blog。正确的选项取决于您的代码库,但如果可能,我建议使用async
工厂方法。选项包括:
如果您绝对无法使用我在博客上描述的其中一个选项,那么您可以在所有ConfigureAwait(false)
方法中使用async
,然后使用Wait()
来解决此问题。不会死锁。但是,这些将在这些异步方法调用期间阻塞UI线程(这种方式首先使它们失去async
的目的......)