【发布时间】:2021-04-03 16:34:21
【问题描述】:
从这里: https://devblogs.microsoft.com/premier-developer/dissecting-the-async-methods-in-c/
Task.Run 或 ThreadPool.QueueUserWorkItem 等方法会自动执行此操作。 Task.Run 方法从调用线程中捕获 ExecutionContext 并将其与 Task 实例一起存储。当与任务关联的 TaskScheduler 运行给定的委托时,它使用存储的上下文通过 ExecutionContext.Run 运行它。
普通ExecutionContext流和捕获有什么区别?对我来说,捕获意味着非常具体的东西——对象状态的快照。就像,闭包在匿名方法/本地方法/等中捕获,它作为字段生成并且具有自己的值,不再反映原始值源(变量)的状态。
所以当我们谈论捕获当前线程的上下文时 - 这与正常的上下文流不同吗?就像,在正常流程中,状态始终是最新的,所以如果父线程上的文化发生变化,孩子会意识到,但是如果EC 被捕获 - 现在子线程只是获取那个时间捕获的快照?我理解正确吗? MSDN 文档在“流”/“捕获”术语的用法上确实不一致。
现在,我们有一个非常重要的观察:流动的 ExecutionContext 在语义上与捕获和发布到 SynchronizationContext 非常不同。
https://devblogs.microsoft.com/pfxteam/executioncontext-vs-synchronizationcontext/
当您流动 ExecutionContext 时,您从一个线程捕获状态,然后恢复该状态,使其在提供的委托执行期间处于环境状态。当您捕获和使用 SynchronizationContext 时,情况并非如此。捕获部分是相同的,因为您正在从当前线程中获取数据,但是您随后会以不同的方式使用该状态。使用 SynchronizationContext.Post 您只需使用捕获的状态来调用委托,而不是在调用委托期间使该状态成为当前状态。 委托运行的地点、时间和方式完全取决于 Post 方法的实现。
这对我来说毫无意义。捕获上下文并在其上发布的想法(在具有 UI 线程的 UI 应用程序的示例中)是在相同的上下文中取回该线程(以更新 UI,duh)。但是如果“委托运行的地点、时间和方式完全取决于 Post 方法的实现。”那么你怎么能确保这一点呢?
【问题讨论】:
标签: c# .net multithreading