2012-03-22 323 views
6

我想了解ExecutionContext實際上在.NET Framework 4.0及更高版本中的工作原理。該文檔指出,在使用Thread.Start和大多數線程池操作時,託管原則,同步,語言環境和用戶上下文都將流向新線程。但在實踐中我看不到這一點。.NET ExecutionContext如何實際工作?

這裏是如果同步內容和管理原則流開始一個新的線程時測試一個簡單的控制檯應用程序...

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在現實中做什麼的描述以及它爲什麼有用?

回答

8

這是非常具有誤導性的文檔。我無法回答你的問題的更廣泛的主旨,但我可以告訴你爲什麼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默認。無論ExecutionContext.SuppressFlow()如何,它也通過CallContext.Principal。因此,解釋了爲什麼你看到了你所看到的內容,但不是什麼時候它可能有用,或者爲什麼這些文檔是錯誤的!