我是 .NET 框架中提供的异步功能的新手
所以据我了解,async 关键字提供的好处是,当线程调用异步方法时,它可以在等待点返回并正常恢复运行。
我的问题是从那一点返回之后,线程在做什么?是否可以用于运行线程池中的其他任务项,如果可以,还必须有上下文切换?如果没有,为什么不在那里旋转?
===== 所以会有其他线程来接管异步函数的未完成部分,这个上下文切换是如何发生的,比如这些状态存储在哪里?以及另一个线程如何获取这些状态
我是 .NET 框架中提供的异步功能的新手
所以据我了解,async 关键字提供的好处是,当线程调用异步方法时,它可以在等待点返回并正常恢复运行。
我的问题是从那一点返回之后,线程在做什么?是否可以用于运行线程池中的其他任务项,如果可以,还必须有上下文切换?如果没有,为什么不在那里旋转?
===== 所以会有其他线程来接管异步函数的未完成部分,这个上下文切换是如何发生的,比如这些状态存储在哪里?以及另一个线程如何获取这些状态
当您的代码遇到await
表达式时(假设 awaitable 未同步完成),控制权返回到调用方法,就像您编写了return;
.
(它返回一个Task<T>
调用者可以用来等待异步部分的完成)
然后调用方法将继续执行直到它返回(它通常会立即返回,因为它也是await
返回的任务),依此类推,直到它到达调用堆栈(面向用户的部分)的顶部。
一旦它到达调用堆栈的顶部,该线程将执行它自然执行的任何操作。
如果它是一个 UI 线程,它将返回到消息循环,保持 UI 响应。
如果它是 ThreadPool 线程(或 ASP.Net 工作线程),它将返回池并(同步)等待更多工作。
如果它是一个“原始”线程(控制台应用程序中的主线程,或者一个new Thread()
,它将终止。
是的,线程返回并可以做其他工作。
至于why not just spin there
,因为它可以做其他工作。当线程有机会工作时,强制线程保持空闲是没有意义的。
如果您不关心哪个线程实际上会继续执行工作,那么您可以使用 Task.ConfigureAwait,如下所示:
await foo.DoSomethingAsync().ConfigureAwait(continueOnCapturedContext: false);