2011-01-11 9 views
7

मैं SynchronizationContext कक्षा के बारे में सीख रहा हूं। मैं WinForm/WPF अनुप्रयोग के संदर्भ में SynchronizationContext.SetSynchronizationContext() पर कॉल करने के लिए सामान्य उपयोग परिदृश्यों को समझने की कोशिश कर रहा हूं। धागे के SynchronizationContext को सेट करने का क्या अर्थ है? मुझे यह कब करना चाहिए और क्यों? इसके अलावा, अगर मैं इसे सेट करता हूं, तो क्या मुझे इसे किसी बिंदु पर अनसेट करना चाहिए?एक UI अनुप्रयोग में सिंक्रनाइज़ेशन कॉन्टेक्स्ट.SetSynchronizationContext() को कब कॉल करें?

संपादित करें:

उसके जवाब में, @Hans Passant पूछा क्यों मैं SetSynchronizationContext() विचार कर रहे थे। मेरे पास विचार है कि वर्क थ्रेड पर संदर्भ सेट करना है ताकि उस थ्रेड पर चल रहे कोड का उपयोग करने के लिए एक संदर्भ होगा।

private void button3_Click(object sender, EventArgs e) 
{ 
    var syncContext = SynchronizationContext.Current; 
    Task.Factory.StartNew(() => 
    { 
     // Setup the SynchronizationContext on this thread so 
     // that SomeAsyncComponentThatNeedsACurrentContext 
     // will have a context when it needs one 
     if (SynchronizationContext.Current == null) 
      SynchronizationContext.SetSynchronizationContext(syncContext); 

     var c = new SomeAsyncComponentThatNeedsACurrentContext(); 
     c.DoSomething(); 

    }); 
} 

उत्तर

12

आपको इसे सामान्य रूप से सेट करने के लिए सामान्य UI क्लास लाइब्रेरी में छोड़ देना चाहिए। Winforms स्वचालित रूप से WindowsFormsSynchronizationContext इंस्टेंस स्थापित करता है, WPF एक डिस्पैचर सिंक्रनाइज़ेशन कॉन्टेक्स्ट स्थापित करता है, ASP.NET एक AspNetSynchronizationContext इंस्टॉल करता है, एक स्टोर ऐप WinRTSynchronizationContext, आदि को स्थापित करता है। अत्यधिक विशिष्ट सिंक्रनाइज़ेशन प्रदाता जो यूआई थ्रेड घटनाओं को प्रेषित करने के तरीके से ट्यून किए जाते हैं।

इन अनुप्रयोग वातावरण उनके मुख्य धागे का उपयोग करने के तरीके के बारे में कुछ खास है। वे सभी एक प्रेषक पाश को लागू करते हैं और नोटिफिकेशन प्राप्त करने के लिए थ्रेड-सुरक्षित कतार का उपयोग करते हैं। आमतौर पर विंडोज जीयूआई प्रोग्रामिंग में "संदेश लूप" के रूप में जाना जाता है। उपभोक्ता को कार्यान्वित करने वाले प्रेषक लूप के साथ यह निर्माता/उपभोक्ता समस्या का एक सामान्य समाधान है।

कार्यकर्ता थ्रेड के लिए अपना स्वयं का सिंक्रनाइज़ेशन प्रदाता बनाना पहले आवश्यक है कि ऐसा धागा इसी तंत्र को लागू करता है। दूसरे शब्दों में, आपको एक थ्रेड-सुरक्षित कतार की आवश्यकता होगी, जैसे ConcurrentQueue, और थ्रेड को कतार से अधिसूचनाएं पुनर्प्राप्त करने और उन्हें निष्पादित करने के लिए लिखा जाना चाहिए। एक प्रतिनिधि वस्तु एक अच्छी पसंद होगी। अब आपको पोस्ट विधि को लागू करने में कोई समस्या नहीं होगी, बस कतार में SendOrPostCallback प्रतिनिधि को जोड़ें। प्रेषण विधि को लागू करने के लिए अतिरिक्त कार्य की आवश्यकता है, थ्रेड को यह संकेत देने की आवश्यकता है कि प्रतिनिधि को पुनर्प्राप्त और निष्पादित किया गया था। इसलिए कतार ऑब्जेक्ट को ऑटोरसेट इवेंट की भी आवश्यकता होती है।

ध्यान दें कि आपका धागा अब आम तौर पर उपयोगी थ्रेड बनने से कैसे रोकता है, यह इन अधिसूचनाओं को प्रेषित करके नीचे गिर जाता है। और मौजूदा सिंक्रनाइज़ेशन प्रदाता पहले से ही यह सब कैसे करते हैं। तो यदि आपका ऐप एक विनफॉर्म ऐप है तो आप अपने वर्कर थ्रेड पर डमी अदृश्य फॉर्म के साथ एप्लिकेशन.रुन() को भी कॉल कर सकते हैं। और आप स्वचालित रूप से इसके सिंक्रनाइज़ेशन प्रदाता को मुफ्त में प्राप्त कर लेंगे।

+0

का उपयोग करने की आवश्यकता नहीं है, मेरे प्रश्न के लिए अद्यतन देखें। – Sylvain

+0

क्या मेरा अपडेट आपके उत्तर को बदलता है? क्या आपको लगता है कि एक वर्कर थ्रेड पर सिंक्रनाइज़ेशन कॉन्टेक्स्ट सेटिंग को इससे बचा जाना चाहिए? – Sylvain

+0

मैं वास्तव में यह सुनना चाहता हूं कि आप इसके बारे में क्या सोचते हैं ... धन्यवाद – Sylvain

1

एमएसडीएन पत्रिका के फरवरी 2011 अंक में Google लेख चर्चा सिंक्रनाइज़ेशन कॉन्टेक्स और .NET ब्रह्मांड में उनके विभिन्न कार्यान्वयन थे।

http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

मेरे लिए, यह वास्तव में ऊपर स्पष्ट मदद की इस मुद्दे पर भ्रम हैं। सामान्य रूप से, जैसा कि हंस कहते हैं, एक WinForms/WPF अनुप्रयोग में, आपको SetSynchronizationContext()