【发布时间】:2020-06-30 06:24:32
【问题描述】:
我从来没有机会深入了解 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 线程实际上会在带有 event hadnler 的方法上停止。
但是,令我惊讶的是,windows 是响应式的,一切都运行良好,但我没想到会这样。谁能解释一下这是怎么回事?
看完this post后,我还是有疑问,如果await是异步的,在我的例子中没有阻塞UI线程,为什么线程不继续到下一行MessageBox?那么 UI 线程如何进行呢?
await 之后的代码只是另一个Task,就像在ContinueWith 中一样,这是个好主意吗?但它又回到了 UI 上下文?
【问题讨论】:
-
async void表示 UI 线程不等待它。 -
"windows 响应迅速,一切运行良好,但我没想到" -- 然而,正是
await的点。该方法在该点返回,并在等待的对象完成后恢复执行。与此同时,该线程被释放以做它想做的任何其他事情。这是 async/await 如何工作的基本,我们在网站上有很多问题(数百,如果不是数千)已经很好地解释了所有这些。请参阅标记为重复的最引用/最彻底的之一。 -
我绝不是异步专家,但据我了解,一旦您的异步方法中的代码到达
await关键字,流程将返回调用方法,直到等待的任务完成,然后流程才会恢复到异步方法的其余部分。 -
await不是Wait。当代码遇到await关键字时,该方法会在注册一个延续到可等待对象的完成后立即返回。延续包含await行下方的任何内容。在您的情况下,它包含MessageBox.Show命令。当 awaitable 完成时,注册的 continuation 将运行。 -
如果不是简洁的
await有一个更具描述性的名称,例如continueAfterCompletionOf,那么这个运算符可能不会那么混乱。当然,这么长的关键字会有其他缺点。 ??????
标签: c# async-await