अपडेट करें
C # 6 के रूप में, इस प्रश्न का उत्तर है:
SomeEvent?.Invoke(this, e);
मैं अक्सर निम्नलिखित सलाह सुनता / पढ़ता हूं:
इससे पहले कि आप इसकी जांच करें null
और आग लगा दें, हमेशा किसी घटना की प्रतिलिपि बनाएँ । यह थ्रेडिंग के साथ एक संभावित समस्या को समाप्त कर देगा जहां घटना null
ठीक उसी स्थान पर हो जाती है , जहां आप नल की जांच करते हैं और जहां आप घटना को फायर करते हैं:
// Copy the event delegate before checking/calling
EventHandler copy = TheEvent;
if (copy != null)
copy(this, EventArgs.Empty); // Call any handlers on the copied list
अपडेट किया गया : मैंने अनुकूलन के बारे में पढ़ने से सोचा था कि इसके लिए ईवेंट सदस्य को अस्थिर होना पड़ सकता है, लेकिन जॉन स्कीट ने अपने जवाब में कहा कि सीएलआर कॉपी को ऑप्टिमाइज़ नहीं करता है।
लेकिन इस बीच, इस मुद्दे को भी होने के लिए, किसी अन्य सूत्र ने कुछ इस तरह किया होगा:
// Better delist from event - don't want our handler called from now on:
otherObject.TheEvent -= OnTheEvent;
// Good, now we can be certain that OnTheEvent will not run...
वास्तविक अनुक्रम यह मिश्रण हो सकता है:
// Copy the event delegate before checking/calling
EventHandler copy = TheEvent;
// Better delist from event - don't want our handler called from now on:
otherObject.TheEvent -= OnTheEvent;
// Good, now we can be certain that OnTheEvent will not run...
if (copy != null)
copy(this, EventArgs.Empty); // Call any handlers on the copied list
वह बिंदु OnTheEvent
जो लेखक के अनसब्सक्राइब होने के बाद चलता है, और फिर भी वे ऐसा होने से बचने के लिए विशेष रूप से अनसब्सक्राइब करते हैं। निश्चित रूप से वास्तव में जिस चीज की आवश्यकता होती है वह है कस्टम एक्सेस इम्प्लीमेंटेशन जिसमें add
और एक्सेसर्स में उपयुक्त सिंक्रोनाइज़ेशन होता है remove
। और इसके अलावा अगर किसी घटना को निकाल दिया जाता है तो ताला बंद होने पर संभावित गतिरोध की समस्या होती है।
तो क्या यह कार्गो कल्ट प्रोग्रामिंग है ? ऐसा लगता है कि - बहुत से लोग अपने कोड को कई धागों से बचाने के लिए यह कदम उठा रहे होंगे, जब वास्तव में मुझे ऐसा लगता है कि ईवेंट्स को बहु-थ्रेडेड डिज़ाइन के भाग के रूप में उपयोग किए जाने से पहले इसकी तुलना में बहुत अधिक देखभाल की आवश्यकता होती है । नतीजतन, जो लोग अतिरिक्त देखभाल नहीं कर रहे हैं वे इस सलाह को अनदेखा कर सकते हैं - यह केवल एकल-थ्रेडेड प्रोग्राम के लिए कोई समस्या नहीं है, और वास्तव में, volatile
अधिकांश ऑनलाइन उदाहरण कोड की अनुपस्थिति को देखते हुए , सलाह नहीं हो सकती है सभी पर प्रभाव।
(और क्या यह केवल delegate { }
सदस्य घोषणा पर खाली असाइन करने के लिए बहुत आसान नहीं है ताकि आपको null
पहली बार जांचने की आवश्यकता न हो ?)
अपडेट किया गया:यदि यह स्पष्ट नहीं था, तो मैंने सभी परिस्थितियों में एक शून्य संदर्भ अपवाद से बचने के लिए - सलाह के इरादे को समझ लिया। मेरा कहना है कि यह विशेष रूप से अशक्त संदर्भ अपवाद केवल तब हो सकता है जब घटना से एक और धागा निकल रहा हो, और ऐसा करने का एकमात्र कारण यह सुनिश्चित करना है कि उस घटना के माध्यम से कोई और कॉल प्राप्त नहीं होगी, जो स्पष्ट रूप से इस तकनीक द्वारा हासिल नहीं की गई है । आप एक दौड़ की स्थिति को छिपाएंगे - इसे प्रकट करना बेहतर होगा! यह अशक्त अपवाद आपके घटक के दुरुपयोग का पता लगाने में मदद करता है। यदि आप चाहते हैं कि आपके घटक को दुर्व्यवहार से बचाया जाए, तो आप WPF के उदाहरण का अनुसरण कर सकते हैं - अपने निर्माता में थ्रेड आईडी स्टोर करें और फिर एक अपवाद फेंकें यदि कोई अन्य धागा आपके घटक के साथ सीधे संपर्क करने का प्रयास करता है। या फिर वास्तव में थ्रेड-सुरक्षित घटक (एक आसान काम नहीं) को लागू करें।
तो मैं यह मानता हूं कि यह कॉपी / चेक मुहावरा है कि कार्गो पंथ प्रोग्रामिंग है, जो आपके कोड में गड़बड़ी और शोर जोड़ रहा है। वास्तव में अन्य धागों से बचाने के लिए बहुत अधिक कार्य की आवश्यकता होती है।
एरिक लिपर्ट के ब्लॉग पोस्ट के जवाब में अपडेट:
इसलिए एक बड़ी बात यह है कि मैं इवेंट हैंडलर्स के बारे में याद कर रहा था: "इवेंट हैंडलर को इवेंट के अनसब्सक्राइब होने के बाद भी कॉल करने के लिए मजबूत होना आवश्यक है", और जाहिर है इसलिए हमें केवल इवेंट की संभावना के बारे में ध्यान रखना होगा प्रतिनिधि होना null
। क्या घटना संचालकों पर कहीं भी आवश्यकता है?
और इसलिए: "इस समस्या को हल करने के अन्य तरीके हैं; उदाहरण के लिए, हैंडलर को खाली कार्रवाई करने के लिए आरंभीकरण करना जो कभी भी हटाया नहीं जाता है। लेकिन एक अशक्त जांच करना मानक पैटर्न है।"
तो मेरे सवाल का एक शेष टुकड़ा है, स्पष्ट-अशक्त "मानक पैटर्न" की जांच क्यों है? विकल्प, खाली प्रतिनिधि को असाइन करने के लिए, केवल = delegate {}
ईवेंट घोषणा में जोड़ा जाना आवश्यक है , और यह उन हर जगह से बदबूदार समारोह के छोटे ढेर को समाप्त करता है जहां घटना को उठाया जाता है। यह सुनिश्चित करना आसान होगा कि खाली प्रतिनिधि तत्काल करने के लिए सस्ता है। या मैं अभी भी कुछ याद कर रहा हूँ?
निश्चित रूप से यह होना चाहिए कि (जैसा कि जॉन स्कीट ने सुझाव दिया) यह सिर्फ .NET 1.x सलाह है जो मर नहीं गई है, जैसा कि इसे 2005 में किया जाना चाहिए था?
EventName(arguments)
इस घटना के प्रतिनिधि को बिना शर्त आमंत्रित करने का फैसला किया , बजाय इसके कि यह केवल प्रतिनिधि को आमंत्रित करे अगर गैर-अशक्त (अशक्त होने पर कुछ भी न करें)।