C# async/await - 程序如何跟踪调用 "await"的位置?

标签 c# multithreading asynchronous async-await task

<分区>

当正在运行的线程遇到 await 时,内部使用什么机制来“标记”该特定方法最终需要在等待的任务完成时恢复? 考虑以下方法:

public async void DoSomething()
{
   await Task.Run(() => SomeLongRunningWork());
   // Code to resume when the task is done...
   Console.WriteLine("Resuming...");
}

当达到上面的await时,线程池中的一个线程被用来做长时间运行的工作。 此外,调用线程会立即退出 DoSomething() 方法,并在任务完成后“返回”。

调用线程如何知道如何在某个时刻“返回”?内部正在发生什么来实现这一目标?

最佳答案

当方法包含 await 时,编译器创建所谓的异步状态机。任务是 await ed 存储在 await 之后的所有内容被标记为任务的延续。

通过状态机,一个AsyncTaskMethodBuilder<> , 和一个 TaskAwaiter<> ,基础设施跟踪执行和同步上下文,捕获局部变量并最终跟踪原始 Task状态在等待完成时。它通过循环(调用内部 MoveNext 方法)直到任务完成、被取消或出错(由于异常)来完成此操作。假设是前者,然后在适当的上下文中调用延续。抛出异常时,AggregateException你通常会得到 Task被“展开”(抛出第一个异常)以模仿正常的同步方法的体验。

这是一个整体的简化。有各种优化和一堆机制可以使这一切正常进行。关于这个主题的好博客,我建议这个 Microsoft series关于异步方法。

关于C# async/await - 程序如何跟踪调用 "await"的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62724567/

相关文章:

c# - 条件编译已关闭 VS 2012 razor javascript

c# - 获取在RichTextBox中输入的最后一个词c#

c# - ASP.Net:Server.Transfer() 导致 HttpModule ReleaseRequestState 处理程序未被调用?

c++ - C++ 中的 vector 和线程

java - 停止运行多个线程的 Java 服务

c# - 为手动生成的 WCF(客户端)代理实现异步/等待模式

c# - 大数类型

node.js - 在 Nodejs 项目中处理 Controller 发送响应的更好方法是什么?

c# - SocketAsyncEventArgs以及对Socket的混合Async和Sync调用

python - 通过线程+队列或ThreadPoolExecutor使用异步等待吗?