同步上下文,它何时流动,何时不流动

本文关键字:何时 不流动 上下文 同步 何时流 | 更新日期: 2023-09-27 18:32:33

我正在尝试了解SynchronizationContext和朋友。如果我在控制台应用程序的开头设置自定义同步上下文。在什么情况下,当前同步上下文将与我的异步操作一起流动?Task和其他人之间是否存在差异,例如 Delegate.BeginInvoke

void Main()
{
    SynchronizationContext.SetSynchronizationContext(new FooContext());
    Action a = () =>
    {
         var current = SynchronizationContext.Current;
         //current is null here
    };
    a.BeginInvoke(null,null);
    ...sleep

如果我在线程池上执行内容,是否强制将同步上下文分配给当前正在执行我工作的特定线程?

同步上下文,它何时流动,何时不流动

在什么情况下,当前同步上下文将与我的异步操作一起流动?

async方法执行await时,默认情况下它将捕获当前上下文并使用它来恢复async方法。除非null,否则这个上下文是SynchronizationContext.Current的,在这种情况下它是TaskScheduler.Current的。我在 async 介绍博客文章、有关 SynchronizationContext 的 MSDN 文章和有关异步最佳做法的 MSDN 文章中描述了此行为。

Task和其他任务之间是否有区别,例如Delegate.BeginInvoke?

此行为对于asyncawait是唯一的。 Delegate.BeginInvoke 表示"在线程池线程上运行此委托",因此它不会传播SynchronizationContext。更现代的方法(如 Task.Run .

如果我在线程池上执行内容,是否强制将同步上下文分配给当前正在执行我工作的特定线程?

通常,不应在不属于您的线程上安装同步上下文。如果确实在线程池线程上放置了一个线程,则应在线程返回到线程池之前将其删除。更有可能的是,如果您正在安装同步上下文,则永远不应该返回线程(自定义同步上下文通常与该线程的"主循环"相关联(。

在上面的示例中,逻辑调用上下文流动,但不流动同步上下文。 任何说明为什么会这样会很有趣的指针都会很有趣。

其他上下文的记录更少。斯蒂芬·图布(Stephen Toub(在这个问题上有权威的帖子。从本质上讲,某些数据(例如安全性(必须流动;大多数其他数据没有。