2009-06-24 11 views
5

क्या थ्रेड-सुरक्षित के नीचे कार्यान्वयन है? यदि नहीं, तो मुझे क्या याद आ रहा है? क्या मुझे कहीं volatile कीवर्ड चाहिए? या OnProcessingCompleted विधि में कहीं लॉक? यदि हां, तो कहाँ?सी #: थ्रेड-सुरक्षित घटनाएं

public abstract class ProcessBase : IProcess 
{ 
    private readonly object completedEventLock = new object(); 

    private event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; 

    event EventHandler<ProcessCompletedEventArgs> IProcess.ProcessCompleted 
    { 
     add 
     { 
      lock (completedEventLock) 
       ProcessCompleted += value; 
     } 
     remove 
     { 
      lock (completedEventLock) 
       ProcessCompleted -= value; 
     } 
    } 

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e) 
    { 
     EventHandler<ProcessCompletedEventArgs> handler = ProcessCompleted; 
     if (handler != null) 
      handler(this, e); 
    } 
} 

नोट: कारण है कि मैं निजी घटना और स्पष्ट इंटरफेस सामान है, क्योंकि यह एक सार आधार वर्ग है। और इससे प्राप्त वर्गों को उस घटना के साथ कुछ भी नहीं करना चाहिए। वर्ग आवरण जोड़ा गया है ताकि यह और अधिक स्पष्ट है =)

+0

(टिप्पणी करने के लिए उत्तर दिया) –

उत्तर

4

निजी ProcessCompleted सदस्य के लिए कोई ज़रूरत नहीं एक event होने के लिए नहीं है - यह सिर्फ एक क्षेत्र हो सकता है: - वर्ग के भीतर यह हमेशा क्षेत्र के लिए सीधे चला जाता है , इसलिए event सामान वैसे भी खो गया है।

दृष्टिकोण आप एक स्पष्ट ताला वस्तु के साथ दिखाया है नहीं है ज्यादा अधिक धागे की सुरक्षित सिर्फ एक क्षेत्र की तरह घटना की तुलना में (यानी public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - फर्क सिर्फ इतना है कि आप ताला लगा नहीं कर रहे हैं "इस" है (जो एक अच्छी बात है - आप आदर्श बचने this पर ताला लगा होना चाहिए)। .. "हैंडलर चर" दृष्टिकोण सही एक है, लेकिन अभी भी side-effects you should be aware of हैं

+0

जोड़ा गया क्यों मैंने निजी घटनाक्रम और मेरे प्रश्न के लिए स्पष्ट घटना सामग्री का उपयोग किया। क्या इसकी अभी भी आवश्यकता नहीं है? और उस अंतर से आपका क्या मतलब है? क्या कोई सार्वजनिक ईवेंट इवेंट हैंडलर SomeEvent स्वचालित रूप से इस पर लॉक करता है? – Svish

+2

हां; फ़ील्ड जैसी घटनाएं (यानी एक स्पष्ट ऐड/निकाले के बिना एक ईवेंट) में एक इनबिल्ट लॉक है (यह); भाषा spec (एमएस संस्करण) में 10.8.1 देखें; हालांकि, यह कक्षा के अंदर कोड द्वारा छोड़ा गया है - http://marcgravell.blogspot.com/2009/02/fun-with-field-like-events.html देखें; इसलिए एक * निजी * घटना के रूप में, जोड़ें/निकालें (और इस प्रकार ताला) कभी भी उपयोग नहीं किया जाता है। एक स्पष्ट इंटरफ़ेस कार्यान्वयन के लिए, कोड ठीक है, और आपको लॉक को जोड़ना होगा, जो आपने किया है - और "लॉक (यह)" से तर्कसंगत * बेहतर *। इसके साथ चिपकाएं ;- –

+0

alrighty =) – Svish

5

जब आप हैंडलर भी लाने लॉक करने की आवश्यकता , अन्यथा आपके पास नवीनतम मान नहीं हो सकता है:

protected void OnProcessingCompleted(ProcessCompletedEventArgs e) 
{ 
    EventHandler<ProcessCompletedEventArgs> handler; 
    lock (completedEventLock) 
    { 
     handler = ProcessCompleted; 
    } 
    if (handler != null) 
     handler(this, e); 
} 

नोट एक रेस स्थिति है जहाँ हम हम संचालकों का एक सेट और तो एक हैंडलर से समाप्त कर दी निष्पादित करने के लिए जा रहे हैं तय कर लिया है रोकने नहीं है कि इस है। इसे अभी भी बुलाया जाएगा, क्योंकि हमने इसे मल्टीकास्ट प्रतिनिधि को handler चर में लाया है।

हैंडलर को स्वयं को जागरूक करने के अलावा, इसके बारे में आप इतना कुछ नहीं कर सकते हैं कि इसे अब और नहीं कहा जाना चाहिए।

यह यकीनन बेहतर है बस नहीं घटनाओं धागा सुरक्षित बनाने के लिए प्रयास करने के लिए - निर्दिष्ट करें कि सदस्यता चाहिए सूत्र में केवल परिवर्तन जो घटना को बढ़ा देंगे।

+0

क्या आप वाकई लॉक आवश्यक हैं? प्रतिनिधि अपरिवर्तनीय हैं और असाइनमेंट परमाणु ऑपरेशन है, इसलिए मुझे लगता है कि कोई ताला नहीं है। – TcKs

+0

अपनी पोस्ट पर मेरी टिप्पणियां देखें। इसे थ्रेड-सुरक्षित बनाने के लिए आपको बिल्कुल लॉकिंग की आवश्यकता है। –

+0

हां, "जोड़ें" और "निकालें" में ताले necesary है। लेकिन "ऑनप्रोसेसिंग पूर्ण" में "लॉक" का उपयोग करके मुझे क्या लाभ मिला? – TcKs