如何在使用async/await时修复Win Forms构造函数中的死锁
本文关键字:Forms Win 构造函数 死锁 async await | 更新日期: 2023-09-27 18:26:42
这是我的最小repo情况:
public Form1()
{
Task.Delay(100).Wait(); // Works just fine
this.Await().Wait(); // Blocks indefinitely
}
private async Task Await()
{
await Task.Delay(100);
}
这是怎么回事?为什么这两个人的行为不同?我该怎么做才能使后一个有效?
我的实际案例不那么琐碎,我不能"只使用第一个选项"。
您看到了一个经典的死锁情况,我在博客和MSDN文章中对此进行了描述。简而言之,在await
完成后,async
方法正试图在UI线程上恢复,而您已通过调用Wait
阻止了该线程。
要修复它,理想情况下,您希望一直使用async
(即,永远不要阻塞async
代码)。构造函数在这里造成了困难(因为它们不能是async
);我在博客上探索了几个选项。正确的选项取决于您的代码库,但如果可能的话,我建议使用async
工厂方法。选项包括:
- 异步工厂方法
- 异步延迟初始化
- 异步初始化模式
如果你绝对不能使用我在博客上描述的任何一个选项,那么你可以在所有的async
方法中使用ConfigureAwait(false)
来解决这个问题,这样你的Wait()
就不会死锁。然而,这个将在异步方法调用期间阻塞UI线程(这有点违背了它们最初作为async
的目的…)