简体   繁体   English

在Task内部等待之后的代码执行上下文

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM