SynchronizationContext,它何时流动,何时不流动?

Rog*_*son 6 c# asynchronous synchronizationcontext task-parallel-library

我正在努力学习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
Run Code Online (Sandbox Code Playgroud)

如果我在线程池上执行东西,我是否被迫为当前正在执行我的工作的特定线程分配同步上下文?

Ste*_*ary 5

在什么条件下,当前的同步上下文会与我的异步操作一起流动?

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

Task和其他人之间是否存在差异,例如Delegate.BeginInvoke?

此行为是asyncawait.Delegate.BeginInvoke表示"在线程池线程上运行此委托",因此它不会传播SynchronizationContext.也没有更多的现代方法,如Task.Run.

如果我在线程池上执行东西,我是否被迫为当前正在执行我的工作的特定线程分配同步上下文?

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

在上面的示例中,逻辑调用上下文流但不是同步上下文.任何指向这种情况的指针都会很有趣.

其他情况甚至没有记录.Stephen Toub 在这个问题上明确的帖子.从本质上讲,安全等一些数据必须流动; 大多数其他数据没有.