【问题标题】:How does .NET ExecutionContext actually work?.NET ExecutionContext 是如何实际工作的?
【发布时间】:2012-04-06 14:50:40
【问题描述】:

我试图了解ExecutionContext 在 .NET Framework 4.0 及更高版本中的实际工作方式。文档说,当使用 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 在现实中的作用以及为什么有用的描述?

【问题讨论】:

    标签: .net multithreading executioncontext


    【解决方案1】:

    这是非常具有误导性的文档。我无法回答你问题的更广泛的主旨,但我可以告诉你为什么 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()。所以,解释了为什么你看到你所看到的,但不是什么时候有用,或者为什么文档完全错误!

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2011-09-27
    • 2021-12-16
    • 2013-03-14
    • 2021-03-23
    • 2011-02-11
    • 2017-07-31
    相关资源
    最近更新 更多