Task::ConfigureAwait - 竞争条件?
Task::ConfigureAwait - a race condition?
想象一下调用者创建任务时的情况:
{
var tWithCapturedCtx = Task.Run(...);
var tWithoutCapturedCtx = tWithCapturedCtx.ConfigureAwait(false);
await tWithoutCapturedCtx;
}
是否有可能 tWithCapturedCtx 执行得如此之快以至于延续将在捕获的上下文中执行?
ConfigureAwait
被调用 在继续被添加到任务之前 。 continuation 被添加到配置为不捕获上下文的对象中,因此当它的 continuation 是 运行 时它不会捕获上下文(这实际上是它存在的目的,它不会实现它记录的目的,如果没有)。
Is there a possibility that tWithCapturedCtx will execute so fast that the continuation will be executed on the captured context?
有点。
如果在计算 await
时 tWithCapturedCtx
已经完成(这意味着 tWithoutCapturedCtx
也已经完成),则根本没有继续。 async
方法只是继续同步执行(在同一上下文中)。
但是,如果在评估 await
时 tWithCapturedCtx
尚未完成(这意味着 tWithoutCapturedCtx
也尚未完成),则计划继续执行而不正在捕获上下文。
在 await
检查其可等待对象是否完成与 await
安排继续之间存在另一个甚至更小的竞争条件。如果 awaitable 在 window 内完成,那么延续只是 运行 同步(同样,在相同的上下文中)。
总之,ConfigureAwait(false)
表示"I don't care what context the rest of this method runs in";它不是意味着"run the rest of this method on the thread pool"。如果要说 "run this other code on a thread pool thread",则使用 Task.Run
。
想象一下调用者创建任务时的情况:
{
var tWithCapturedCtx = Task.Run(...);
var tWithoutCapturedCtx = tWithCapturedCtx.ConfigureAwait(false);
await tWithoutCapturedCtx;
}
是否有可能 tWithCapturedCtx 执行得如此之快以至于延续将在捕获的上下文中执行?
ConfigureAwait
被调用 在继续被添加到任务之前 。 continuation 被添加到配置为不捕获上下文的对象中,因此当它的 continuation 是 运行 时它不会捕获上下文(这实际上是它存在的目的,它不会实现它记录的目的,如果没有)。
Is there a possibility that tWithCapturedCtx will execute so fast that the continuation will be executed on the captured context?
有点。
如果在计算 await
时 tWithCapturedCtx
已经完成(这意味着 tWithoutCapturedCtx
也已经完成),则根本没有继续。 async
方法只是继续同步执行(在同一上下文中)。
但是,如果在评估 await
时 tWithCapturedCtx
尚未完成(这意味着 tWithoutCapturedCtx
也尚未完成),则计划继续执行而不正在捕获上下文。
在 await
检查其可等待对象是否完成与 await
安排继续之间存在另一个甚至更小的竞争条件。如果 awaitable 在 window 内完成,那么延续只是 运行 同步(同样,在相同的上下文中)。
总之,ConfigureAwait(false)
表示"I don't care what context the rest of this method runs in";它不是意味着"run the rest of this method on the thread pool"。如果要说 "run this other code on a thread pool thread",则使用 Task.Run
。