等待不会阻塞调用线程

时间:2020-03-19 06:06:47

标签: c# async-await

我从来没有机会深入研究async/await,所以我只是想知道它的作用。

所以我像这样在WinForms应用程序中尝试过:

private async void button2_Click(object sender, EventArgs e)
{
  // In below line I understand the Task is created and scheduled to execute, which in this
  // simple case means, that it executes right away asynchronously.
  var task = Task.Factory.StartNew(() =>
  {
    Task.Delay(5000).Wait();
    return 12;
  });

  // Here we wait for the task to finish, so we don't see MessageBox yet.
  var res = await task;
  MessageBox.Show("Result is :" + res);
}

我的问题是,由于我们正在等待await,所以我希望阻止UI线程,因为我们可以在该线程中继续前进(到MessageBox行)。因此,UI线程实际上在具有事件hadnler的方法上停止。

但是,令我惊讶的是,Windows可以响应,并且一切正常,但是我没想到。谁能解释我发生了什么事?

在阅读this post之后,我仍然怀疑,如果await是异步的并且在我的示例中没有阻塞UI线程,为什么线程不继续使用{{1 }}? UI线程如何进行?

好在MessageBox之后的代码只是另一个await,就像Task中的代码一样吗?但这又回到UI上下文了吗?

1 个答案:

答案 0 :(得分:1)

异步方法非常类似于生成器方法。编译器将在每个await运算符处拆分您的代码。插入代码块以检查任务是否已完成,在这种情况下,该方法将立即继续。或者,如果任务未完成,则注册一个回调以在以后继续执行,然后您的方法返回。

提早返回是异步方法的重点。