Mar*_*knk 5 .net c# asp.net async-await asp.net-web-api
这个问题是在ASP.NET WebApi 2(不是 ASP.NET Core)的上下文中提出的。我试图对这个主题进行自己的研究,但是我找不到明确的答案。
官方的MSDN文档的ConfigureAwait(...)方法的参数规定如下:
true尝试将延续编组回捕获的原始上下文;否则,false。
Stephen Toub进一步解释该attempt关键字如下:
这意味着可能没有任何东西可以编组回......可能没有要捕获的上下文,例如
SynchronizationContext.Current可能返回null。
如果我理解正确,那么 ASP.NET WebApi 2 就不是这种情况,因为AspNetSynchronizationContext存在,对吗?
现在让我们看看以下控制器操作方法:
[HttpGet]
public async Task<String> GetValues()
{
// First half.
var values = await HeavyIo().ConfigureAwait(false);
// Second half.
return values;
}
Run Code Online (Sandbox Code Playgroud)
通过将continueOnCapturedContext: false能够保证所有的是,标为继续// Second half.得到总是在不同的线程中执行?或者,如果异步操作完成时捕获同步上下文的线程将空闲,那么延续将在同一个线程上运行?
当以否定形式询问时,我认为答案非常清楚 - 不能保证后半部分将在与前半部分不同的线程上执行。正如您推测的那样,当延续要执行时,原始线程很可能是幸运的下一个被挑选的可用线程。
还需要注意的是,恢复的是上下文,不一定是线程。在 Windows 消息循环(例如 WinForms UI 线程)的情况下,是运行消息循环的 UI 线程拾取并执行延续,因此使用ConfigureAwait(true),可以保证相同的线程。但是,对于其他 SynchronizationContexts,可能没有特别的理由要求甚至更喜欢原始线程,只要它们认为是“上下文”的任何内容都已恢复;例如HttpContext.CurrentASP.NET 中的 [, identity,culture]。
还有至少理论上HeavyIo()同步完成的机会,在这种情况下无论如何都没有上下文切换,后半部分将简单地在与第一部分相同的线程上继续。我只能从您选择的命名(“重”)中假设您暗示这不会是一种选择。