C# 等待不&x27;t块调用线程

C# 等待不&x27;t块调用线程,c#,async-await,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 execut

我从来没有机会深入研究
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);
}
我的问题是,因为我们正在等待
wait
,所以我希望阻止UI线程,因为我们可以在该线程中进一步(使用
MessageBox
)。所以UI线程实际上停止在带有事件hadnler的方法上

但是,令我惊讶的是,windows的响应速度很快,而且一切都运行得很好,但我没有料到这一点。有人能解释一下发生了什么事吗

阅读之后,我仍然有一个疑问,如果
await
是异步的,并且在我的示例中没有阻止UI线程,那么为什么线程不使用
MessageBox
进入下一行?那么UI线程是如何进行的呢


等待
之后编写代码仅仅是另一个
任务
,就像在
继续执行
一样,这是个好主意吗?但它又回到了UI上下文?

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


提前返回是异步方法的全部要点。

async void
意味着UI线程不会等待它。“windows响应良好,一切正常,但我没料到”——然而,这正是
等待的全部要点。该方法在该点返回,并将在等待的对象完成后恢复执行。同时,该线程被释放,可以做它想做的任何事情。这是async/await如何工作的基础,我们在网站上有很多问题(数百个,如果不是数千个的话)已经很好地解释了这一切。请参阅标记的重复项,以了解引用最多/最彻底的方法之一。我绝不是异步专家,但据我所知,一旦异步方法中的代码达到
await
关键字,流将返回调用方法,直到等待的任务完成,只有这样,流才能恢复到异步方法的其余部分。
Wait
不是
Wait
。当代码点击
await
关键字时,该方法在注册一个延续以完成等待后立即返回。延续包含
wait
行下方的任何内容。在您的示例中,它包含
MessageBox.Show
命令。等待完成后,注册的继续将运行。如果使用更具描述性的名称代替整洁的
await
,例如
continueAfterCompletionOf
,则此运算符可能不会那么混乱。当然,这样长的关键字还有其他缺点。