2012-03-22 26 views
6

ExecutionContext'un aslında .NET Framework 4.0 sürümünde ve üstünde nasıl çalıştığını keşfetmeye çalışıyorum. Belgeler, yönetilen ilkenin, senkronizasyonun, yerel ayarın ve kullanıcı içeriğinin Thread.Start ve çoğu iş parçacığı havuzu işlemlerini kullanırken yeni iş parçacığına aktığını söylüyor. Ama bunu pratikte hiç göremiyorum. İşte .NET ExecutionContext aslında nasıl çalışır?

senkronizasyon bağlam ve yönetilen ilke akış yeni bir iş parçacığı başlatırken eğer test eden basit bir konsol uygulaması ... Yani

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); 
    } 

sonucudur ...

ThreadRun Id=11 Context=False Principle=One 
    ThreadRun Id=12 Context=False Principle=Two 

olduğunu Senkronizasyon bağlamı asla akmaz ve yönetilen prensip belirttiğinizde bile her zaman akar. Temel olarak belgeler tamamen yanlıştır. Öyleyse ExecutionContext'in gerçekte ne yaptığını ve neden yararlı olduğunu açıklayan bir tanım var mı?

cevap

8

Bu oldukça yanıltıcı belgelerdir. Sorunun daha geniş bir itkisine cevap veremem ama neden SynchronizationContext'un akmadığını söyleyebilirim. açıkça varsayılan olarak ExecutionContext.CaptureOptions.IgnoreSyncCtx geçtiği

[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); 
    } 

Not: Eğer Thread.Start kaynağı bakarsak

, sonunda aşağı çağırır. Ayrıca, ExecutionContext.SuppressFlow() öğesinden bağımsız olarak CallContext.Principal geçer. Bu yüzden, gördüğünüz şeyi neden gördüğünüzü açıklıyor, ancak yararlı olabileceği ya da dokümanların neden hatalı olduğu niçin değil!