एक आम बात कॉल दौड़ की स्थिति से बचने के लिए (मल्टी-थ्रेडेड क्षुधा में) जब ट्रिगर घटनाओं यह है:थ्रेड सुरक्षित घटना
EventHandler<EventArgs> temp = SomeEvent;
if (temp != null) temp(e);
"Remember that delegates are immutable and this is why this technique works in theory. However, what a lot of developers don't realize is that this code could be optimized by the compiler to remove the local temp variable entirely. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible."
समस्या (पुस्तक के अनुसार) है कि "इस कोड अनुकूलित किया जा सकता है संकलक द्वारा पूरी तरह से स्थानीय अस्थायी चर दूर करने के लिए। यदि ऐसा होता है, कोड के इस संस्करण पहले संस्करण के समान है, इसलिए एक NullReferenceException अभी भी संभव है "
सी # के माध्यम से CLR के अनुसार, यहां के लिए एक बेहतर तरीका है इवेंट पॉइंटर की प्रतिलिपि बनाने के लिए कंपाइलर को मजबूर करें।
virtual void OnNewMail(NewMailEventArgs e)
{
EventHandler<NewMailEventArgs> temp =
Interlocked.CompareExchange(ref NewMail, null, null);
if (temp != null)
temp(this, e);
}
यहाँ, CompareExchange अशक्त करने के लिए चलाएँ संदर्भ में परिवर्तन अगर यह रिक्त है और चलाएँ में परिवर्तन नहीं करता है, तो यह शून्य नहीं है। दूसरे शब्दों में, तुलना एक्सचेंज न्यूमेल में मूल्य को बिल्कुल नहीं बदलता है, लेकिन यह न्यूमेल के अंदर मूल्य को परमाणु, थ्रेड-सुरक्षित तरीके से वापस कर देता है। रिक्टर, जेफरी (2010-02-12)। सी # के माध्यम से सीएलआर (पृष्ठ 265)। ओर्ली मीडिया - ए किंडल संस्करण।
मैं नेट 4.0 ढांचे पर हूँ, और यकीन है कि यह कैसे संभवतः काम कर सकते हैं, क्योंकि Interlocked.CompareExchange एक स्थान है, न कि घटना के लिए एक संदर्भ के लिए एक संदर्भ की उम्मीद नहीं।
या तो पुस्तक में कोई त्रुटि है, या मैंने इसे गलत व्याख्या की है। क्या किसी ने इस विधि को लागू किया है? या यहां दौड़ की स्थिति को रोकने के लिए एक बेहतर तरीका है?
अद्यतन
यह मेरी गलती थी, iterlocked कोड काम करता है। मैंने अभी गलत कास्टिंग निर्दिष्ट किया था, लेकिन ब्रैडली (नीचे) के अनुसार यह .NET 2.0 और विंडोज़ पर आवश्यक नहीं है।
http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx दिलचस्प हो सकता है – Vlad