[英]Execution context for code after await inside Task
Maybe I misunderstood something, but I always think that by default, when an incomplete Task is awaited, the current “context” is captured and used to resume the method when the Task completes. 也许我误解了一些东西,但是我总是认为默认情况下,当等待不完整的Task时,将捕获当前的“上下文”,并在Task完成时将其用于恢复该方法。 But I found quite strange behavior (at least for me) where this is wrong:
但是我发现了很奇怪的行为(至少对我而言),这是错误的:
private static Task StartTask()
{
return Task.Run(() =>
{
Debug.WriteLine("StartTask thread id = " + Thread.CurrentThread.ManagedThreadId);
});
}
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
await Task.Run(async () =>
{
Debug.WriteLine("Thread id before await task = " + Thread.CurrentThread.ManagedThreadId);
await StartTask().ConfigureAwait(true);
Debug.WriteLine("Thread id after await task = " + Thread.CurrentThread.ManagedThreadId);
});
}
and I receive such result in debug output 我在调试输出中收到这样的结果
Thread id before await task = 12
StartTask thread id = 13
Thread id after await task = 13
Why did code execution context change after await? 为什么等待后代码执行上下文发生变化?
by default, when an incomplete Task is awaited, the current “context” is captured and used to resume the method when the Task completes
默认情况下,当等待不完整的任务时,将捕获当前的“上下文”,并在任务完成时将其用于恢复该方法
That's correct. 没错 The behavior you observed is correct.
您观察到的行为是正确的。
The question is: what is the "context" that is captured? 问题是:捕获的“上下文”是什么? It is the current
SynchronizationContext
, unless it is null
, in which case it is the current TaskScheduler
. 它是当前的
SynchronizationContext
,除非为null
,在这种情况下,它是当前的TaskScheduler
。
When Task.Run
executes your delegate, it is executing it on the thread pool. 当
Task.Run
执行您的委托时,它正在线程池上执行它。 Thus, there is no current SynchronizationContext
. 因此,当前没有
SynchronizationContext
。 So the current TaskScheduler
is used; 因此,使用了当前的
TaskScheduler
。 note that since there is not actually a task executing (the delegate is executed directly on the thread pool), the current TaskScheduler
is the default TaskScheduler
, which represents the thread pool. 请注意,由于实际上并没有执行任务(委托直接在线程池上执行),因此当前
TaskScheduler
是默认TaskScheduler
,它代表线程池。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.