2011-01-06 15 views
6

क्या यह एक्सटेंशन विधि धागा सुरक्षित है?विस्तार विधि धागा सुरक्षित है?

public static class Extensions 
    { 
     public static void Raise<T>(this EventHandler<T> handler, 
     object sender, T args) where T : EventArgs 
     { 
     if (handler != null) handler(sender, args); 
     } 
    } 

या क्या मुझे इसे बदलने की ज़रूरत है?

public static class Extensions 
    { 
     public static void Raise<T>(this EventHandler<T> handler, 
     object sender, T args) where T : EventArgs 
     { 
     var h = handler; 
     if (h!= null) h(sender, args); 
     } 
    } 
+0

थ्रेडिंग के संबंध में घटनाओं के डिजाइन और कार्यान्वयन विवरण http://stackoverflow.com/questions/786383/c-events-and-thread-safety – user44298

उत्तर

9

आपको एक दिलचस्प पाश छेद मिला, यह सबको ऊपर चला गया। नहीं, यह थ्रेड-सुरक्षित नहीं है।

जबकि लगता है जैसे EventHandler <> संदर्भ विधि तर्क के माध्यम से प्रतिलिपि बनाई गई है, यह रनटाइम पर नहीं होता है। एक्सटेंशन विधियों को एक नियमित उदाहरण विधि की तरह रेखांकित किया जा रहा है। वास्तव में, यह है अत्यधिक यह बहुत छोटा है क्योंकि इनलाइन होने की संभावना है। कोई प्रतिलिपि नहीं है, आपको खुद को बनाना होगा।

+1

मैं सकारात्मक नहीं हूं कि आप सही हैं। यह केवल तब लागू होगा जब कॉलिंग फ़ंक्शन विधि पर विधि को कॉल कर रहा था जो किसी अन्य थ्रेड द्वारा संशोधित किया जाएगा (स्थानीय चर के बजाए उदाहरण के लिए कक्षा फ़ील्ड)। मुझे नहीं पता कि जेआईटी उस मामले में ऐसी कॉल को रेखांकित करेगी या नहीं। – tster

+0

हालांकि, यह एक बहुत ही रोचक विषय है। काश मैं काम पर नहीं था और इस समय में खोदने का समय था। – tster

+1

वैसे, घटना बढ़ाना कोड में शून्य परीक्षण यही है। –

7

कोई भी संस्करण थ्रेडसेफ नहीं है, जिसका अर्थ है "थ्रेडसेफ" से आपका क्या मतलब है। अपने दूसरे संस्करण पर विचार करें:

var h = handler;   
    if (h!= null) 
     h(sender, args); 

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

मान लीजिए कि जब अन्य थ्रेड ने ईवेंट फ़ील्ड को शून्य पर सेट किया था, तो उसने कुछ राज्यों को भी बदल दिया कि पिछली सामग्री को सही ढंग से चलाने के लिए आवश्यक है। अब आप एक इवेंट हैंडलर चलाने जा रहे हैं जो उस राज्य पर निर्भर करता है जो सिर्फ दूसरे धागे पर बदल गया था; आप स्टेल ईवेंट हैंडलर चला रहे हैं।

इस समस्या से बचने के लिए कोई आसान तरीका नहीं है; यदि वह स्थिति है जिसमें आप हैं, तो आपको स्थिति से निपटने के लिए अपने थ्रेडिंग तर्क को बेहद सावधानीपूर्वक डिजाइन करना होगा।

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