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

米沙乌

也许我误解了一些东西,但是我总是认为默认情况下,当等待一个不完整的Task时,将捕获当前的“上下文”,并在Task完成时将其用于恢复该方法。但是我发现了很奇怪的行为(至少对我而言),这是错误的:

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);
        });
}

我在调试输出中收到这样的结果

Thread id before await task = 12
StartTask thread id = 13
Thread id after await task = 13

为什么等待后代码执行上下文会发生变化?

斯蒂芬·克莱里(Stephen Cleary)

默认情况下,当等待一个不完整的任务时,将捕获当前的“上下文”,并在任务完成时将其用于恢复该方法

没错 您观察到的行为是正确的。

问题是:捕获的“上下文”是什么?它是电流SynchronizationContext,除非它是电流null在这种情况下,它是电流TaskScheduler

Task.Run执行您的委托时,它正在线程池上执行它。因此,没有电流SynchronizationContext因此使用了电流TaskScheduler请注意,由于实际上没有正在执行的任务(委托直接在线程池上执行),因此当前值TaskScheduler是default TaskScheduler,它代表线程池。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ApplicationLoader内部是否有隐式执行上下文

来自分类Dev

在UI线程上下文中执行代码的正确方法?

来自分类Dev

在沙箱中执行代码,模块在相同的上下文中

来自分类Dev

AsyncTask内部的上下文

来自分类Dev

中断执行上下文

来自分类Dev

NodeJS执行上下文

来自分类Dev

执行上下文混乱

来自分类Dev

NodeJS执行上下文

来自分类Dev

执行上下文混乱

来自分类Dev

为什么不等待Task.Run()同步回UI线程/原始上下文?

来自分类Dev

XCTestExpectation:如何避免在等待上下文结束后调用执行方法?

来自分类Dev

“上下文”在C#异步/等待代码中到底是什么意思?

来自分类Dev

每个内部的If语句丢失上下文

来自分类Dev

根据上下文限制每个内部

来自分类Dev

返回内部函数时,javascript如何保留外部函数的执行上下文?

来自分类Dev

全局执行上下文中没有内部函数的 JavaScript 变量不可用

来自分类Dev

JavaScript中的执行上下文

来自分类Dev

JavaScript中的隔离执行上下文

来自分类Dev

Actor中期货的执行上下文

来自分类Dev

ContextMenuItem上下文函数未执行

来自分类Dev

执行上下文和((此对象))

来自分类Dev

上下文已处理。执行异步

来自分类Dev

执行上下文JavaScript的可变环境

来自分类Dev

执行上下文和return语句

来自分类Dev

Web组件-什么是执行上下文?

来自分类Dev

星号拨号计划:执行上下文

来自分类Dev

Sidekiq作业执行上下文

来自分类Dev

程序的执行上下文是什么?

来自分类Dev

了解经典执行上下文示例