Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET ExecutionContext实际上是如何工作的?_.net_Multithreading_Executioncontext - Fatal编程技术网

.NET ExecutionContext实际上是如何工作的?

.NET ExecutionContext实际上是如何工作的?,.net,multithreading,executioncontext,.net,Multithreading,Executioncontext,我试图发现在.NET Framework的4.0版及更高版本中实际是如何工作的。文档中说,当使用thread.Start和大多数线程池操作时,托管原则、同步、区域设置和用户上下文都流向新线程。但我认为这在实践中根本不起作用 下面是一个简单的控制台应用程序,它测试启动新线程时同步上下文和托管原则是否流动 static void Main(string[] args) { SynchronizationContext.SetSynchronizationContext

我试图发现在.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在现实中的作用以及它为什么有用的描述呢?

这是一篇误导性很强的文档。我无法回答您问题的更广泛要点,但我可以告诉您为什么
SynchronizationContext
无法流动

如果你看一看问题的来源,它最终会导致:

    [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()。因此,解释了为什么您看到了您正在看到的内容,而不是什么时候它可能有用,或者为什么文档是完全错误的