[英]Task::ConfigureAwait - a race condition?
想象一下调用者创建任务时的情况:
{
var tWithCapturedCtx = Task.Run(...);
var tWithoutCapturedCtx = tWithCapturedCtx.ConfigureAwait(false);
await tWithoutCapturedCtx;
}
tWithCapturedCtx 是否有可能执行得如此之快,以至于将在捕获的上下文上执行延续?
tWithCapturedCtx 是否有可能执行得如此之快,以至于将在捕获的上下文上执行延续?
有点。
如果在评估await
时tWithCapturedCtx
已经完成(这意味着tWithoutCapturedCtx
也已经完成),则根本没有继续。 async
方法只是继续同步执行(在同一上下文中)。
然而,如果tWithCapturedCtx
尚未由时间完成await
评价(这意味着tWithoutCapturedCtx
也尚未完成),则继续被调度而不上下文被捕获。
在await
检查其 awaitable 是否完成和await
安排延续之间还有另一个甚至更小的竞争条件。 如果 awaitable 在该窗口内完成,则延续只是同步运行(同样,在相同的上下文中)。
总之, ConfigureAwait(false)
意思是“我不在乎这个方法的其余部分在什么上下文中运行”; 但这并不意味着“线程池运行该方法的其余部分。” 如果您想说“在线程池线程上运行其他代码”,请使用Task.Run
。
在将延续添加到任务之前,会调用ConfigureAwait
。 延续被添加到配置为不捕获上下文的对象中,因此当它的延续运行时它不会捕获上下文(这实际上是它存在的目的,如果它没有)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.