[英]ConfigureAwait(false) doesn't make the continuation code run in another thread
[英]ConfigureAwait(false) - Does the continuation always run on different thread?
在ASP.NET WebApi 2 (不是ASP.NET Core)的上下文中提出此问题。 我已尝试对此主题进行自己的研究,但是我找不到明确的答案。
有关ConfigureAwait(...)
方法参数的官方MSDN文档指出:
true
尝试当元帅的持续回至拍摄的原始上下文; 否则为false
。
斯蒂芬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;
}
通过传递continueOnCapturedContext: false
,可以确保继续标记为// Second half.
总是在不同的线程上执行? 还是有可能如果异步操作完成后捕获同步上下文的线程是空闲的, 那么继续将在同一线程上运行?
当我以否定形式问到这样的答案时,我认为答案很清楚-无法保证下半部分将在与上半部分不同的线程上执行。 正如您推测的那样,当继续执行时,原始线程很可能是幸运的,即将被选中的可用线程。
还需要注意的重要一点是,还原的是上下文 (不一定是线程) 。 在Windows消息循环的情况下(例如WinForms UI线程),运行消息循环的UI线程将拾取并执行继续,因此,通过ConfigureAwait(true)
可以确保相同的线程。 但是,对于其他SynchronizationContext,可能没有特别的理由要求或什至更喜欢原始线程,只要它们认为是“上下文”的内容得以恢复即可。 例如,ASP.NET中的HttpContext.Current
[,身份,文化]。
从理论上讲, HeavyIo()
同步完成也至少有一个机会,在这种情况下,无论如何都不会进行上下文切换,并且后半部分将继续与前半部分在同一线程上继续。 我只能从您的命名选择(“繁重”)中假设您暗示这将不是一种选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.