2012-03-22 16 views
6

मैं यह जानने की कोशिश कर रहा हूं कि ExecutionContext वास्तव में संस्करण 4.0 और .NET Framework के ऊपर कैसे काम करता है। प्रलेखन का कहना है कि प्रबंधित सिद्धांत, सिंक्रनाइज़ेशन, लोकेल और उपयोगकर्ता संदर्भ थ्रेड.स्टार्ट और अधिकांश थ्रेड पूल संचालन का उपयोग करते समय सभी नए धागे पर आते हैं। लेकिन मैं इसे अभ्यास में बिल्कुल काम नहीं कर सकता।.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 भी पास करता है। तो, बताता है कि आप जो देख रहे हैं उसे क्यों देख रहे हैं, लेकिन जब यह उपयोगी हो या दस्तावेज़ क्यों गलत हो जाएं!

संबंधित मुद्दे