考虑这个简单的async
方法:
private static async Task<int> foo()
{
await Task.Delay(1500);
return 1;
}
如果我在WinForm
应用程序中执行以下操作,正如我所料,它会死锁
private void Form1_Load(object sender, EventArgs e)
{
var fooTask = foo();
fooTask.Wait();
}
但是,如果我在ConsoleApplication
中执行相同操作(不会死锁)
static void Main(string[] args)
{
var fooTask = foo();
fooTask.Wait();
}
为什么会这样? Task
不能继续,因为上下文线程被“阻止”了吗?
答案 0 :(得分:3)
因为WinForms应用程序有一个SynchronizationContext。这意味着,每当您等待异步操作时,操作将在同一个SynchronizationContext上继续(默认情况下)。
您可以通过调用不捕获SynchronizationContext的ConfigureAwait(false)来更改此行为。
在您的情况下,此SynchronizationContext用于UI线程。因此,当你执行
await Task.Delay(1500)
继续代码将在UI线程上执行。但与此同时,由于
,UI线程被阻止但是,ConsoleApplications没有SynchronizationContext,因此可以在不同的线程上执行异步操作的继续。fooTask.Wait()