2010-02-05 22 views
13

मुझे निम्नलिखित मामले में ईवेंट लॉक करना चाहिए:क्या मुझे 'ईवेंट' लॉक करना चाहिए?

ईवेंट foo;

थ्रेड ए: foo + = हैंडलर को कॉल करेगा;

धागा बी: foo - = हैंडलर कॉल करेगा;

क्या मुझे foo लॉक करना चाहिए?

+1

जॉन का जवाब अच्छा है, लेकिन जवाब देने से पहले, मैं वापस पूछूंगा कि आप पहले स्थान पर लॉक क्यों करना चाहते हैं। * आपको विश्वास है कि आपके पास क्या समस्या है, और आपको क्यों लगता है कि लॉकिंग इसे हल करता है? * मैं कई समस्याओं के बारे में सोच सकता हूं जो आपके पास बहुप्रचारित घटनाओं के आसपास हो सकते हैं; आप किस समस्या के बारे में चिंतित थे, इस पर निर्भर करते हुए आप विभिन्न लॉकिंग तकनीकों का उपयोग करेंगे। –

उत्तर

24

foo पर लॉक करना एक बुरा विचार है, क्योंकि मूल्य हर बार बदल जाएगा।

private readonly object eventLock = new object(); 
private EventHandler fooHandler; 

public event EventHandler Foo 
{ 
    add 
    { 
     lock (eventLock) 
     { 
      fooHandler += value; 
     } 
    } 
    remove 
    { 
     lock (eventLock) 
     { 
      fooHandler -= value; 
     } 
    } 
} 

private void OnFoo(EventArgs e) 
{ 
    EventHandler handler; 
    lock (eventLock) 
    { 
     handler = fooHandler; 
    } 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

ध्यान दें कि अगर आप एक क्षेत्र की तरह घटना, इस तरह का उपयोग करें:: तो

public event EventHandler Foo; 

आप स्वचालित रूप से एक प्राप्त "करेंगे आप एक चर जो नहीं परिवर्तन पर ताला चाहिए लॉक (यह) "जोड़ने/हटाने पर, हालांकि इसे कॉल करने से पहले हैंडलर लाने पर आपको इसे मैन्युअल रूप से जोड़ना होगा (मान लें कि आप यह सुनिश्चित करना चाहते हैं कि आपने हाल ही में लिखित मूल्य पढ़ा है)। व्यक्तिगत रूप से मैं "इस" पर लॉक करने का प्रशंसक नहीं हूं, लेकिन आपको कोई फर्क नहीं पड़ता - और यह निश्चित रूप से सरल कोड बनाता है।

+0

@ जोन, मैं एक फ़ील्ड जैसी घटना का उपयोग कर रहा हूं, इसलिए मुझे जोड़ने/निकालने पर लॉक करने की आवश्यकता नहीं है, क्या मैं सही हूँ? – Benny

+0

@ जोन, मैं इवेंट हैंडलर को सीधे ईवेंट का उपयोग करके कॉल कर रहा हूं, जैसे कि foo(), ईवेंट से हैंडलर नहीं ला रहा है, क्या मुझे लॉक जोड़ना चाहिए? – Benny

+1

@ बेनी: यदि आप फ़ील्ड-जैसी घटना का उपयोग कर रहे हैं तो आपके पास लॉक करने के लिए * जोड़ें/निकालें नहीं है। यदि आप ईवेंट हैंडलर को सीधे कॉल कर रहे हैं, तो आप इसके खिलाफ कैसे रक्षा कर रहे हैं? ध्यान दें कि आप केवल 'if (foo! = Null) {foo (...) का उपयोग नहीं कर सकते हैं; } '' foo' के रूप में * परीक्षण के बाद * शून्य हो सकता है। इसके अलावा यह गारंटी नहीं देगा कि आपको नवीनतम मूल्य मिलेगा - यही कारण है कि मुझे अपने 'ऑनफू' विधि में लॉकिंग मिल गई है। (मेमोरी मॉडल मजेदार चीजें कर सकते हैं ...) –

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