.NET ExecutionContext究竟是如何工作的?

9
我正在研究在.NET Framework 4.0及以上版本中ExecutionContext的实际工作原理。文档指出,使用Thread.Start和大多数线程池操作时,托管原则、同步、区域设置和用户上下文都会流到新线程中。但是,在实践中我却没有看到这种情况发生。

这里有一个简单的控制台应用程序,测试同步上下文和托管原则是否会在启动新线程时传递...

    static void Main(string[] args)
    {
        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("One"), null);

        Thread t1 = new Thread(new ThreadStart(ThreadRun));
        t1.Start();
        t1.Join();

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Two"), null);

        AsyncFlowControl aFC = ExecutionContext.SuppressFlow();
        Thread t2 = new Thread(new ThreadStart(ThreadRun));
        t2.Start();
        t2.Join();
        aFC.Undo();

        Console.Read();
    }

    static void ThreadRun()
    {
        Console.WriteLine("ThreadRun Id={0} Context={1} Principle={2}", 
            Thread.CurrentThread.ManagedThreadId, 
            (SynchronizationContext.Current != null), 
            Thread.CurrentPrincipal.Identity.Name);
    }

结果是...
    ThreadRun Id=11 Context=False Principle=One
    ThreadRun Id=12 Context=False Principle=Two

所以同步上下文从不流动,托管原则总是流动,即使您指定不应该这样做。基本上,文档完全错误。那么ExecutionContext实际上是做什么的,为什么它很有用呢?
1个回答

10

这份文档非常误导人。我无法回答你问题的更广泛部分,但我可以告诉你为什么 SynchronizationContext 没有被流动。

如果你查看 Thread.Start 的源代码,最终会调用:

    [SecuritySafeCritical]
    private void Start(ref StackCrawlMark stackMark)
    {
      this.StartupSetApartmentStateInternal();
      if (this.m_Delegate != null)
        ((ThreadHelper) this.m_Delegate.Target).SetExecutionContextHelper(ExecutionContext.Capture(ref stackMark, ExecutionContext.CaptureOptions.IgnoreSyncCtx));
      this.StartInternal(CallContext.Principal, ref stackMark);
    }

需要注意的是,默认情况下它显式地传递 ExecutionContext.CaptureOptions.IgnoreSyncCtx。 它还传递了 CallContext.Principal,无论是否调用了 ExecutionContext.SuppressFlow() 方法。 因此,这解释了您看到的现象,但并没有说明何时会有用,或者文档为什么完全错误!


https://devblogs.microsoft.com/pfxteam/executioncontext-vs-synchronizationcontext/ - Cristian Diaconescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接