2008-11-18 19 views
155

अगर मैं निम्नलिखित कोड है:क्या ईवेंट हैंडलर कचरा संग्रह होने से रोकते हैं?

MyClass pClass = new MyClass(); 
pClass.MyEvent += MyFunction; 
pClass = null; 

विल pClass हो कचरा एकत्र? या जब भी वे होते हैं तब भी यह घटनाओं को फायर कर देगा? कचरा संग्रह की अनुमति देने के लिए मुझे निम्नलिखित करने की आवश्यकता होगी?

MyClass pClass = new MyClass(); 
pClass.MyEvent += MyFunction; 
pClass.MyEvent -= MyFunction; 
pClass = null; 
+9

मैं इस प्रश्न में दिलचस्पी रखने वाले पाठकों को तात्कालिक रूप से सुझाव देने जा रहा हूं कि हल्के घटनाओं/कमजोर घटना पैटर्न से परिचित होना उपयुक्त हो सकता है, जो कचरा संग्रहण होने से नहीं रोकते हैं। इस विषय के लिए एक अच्छा SO बूटस्ट्रैप http://stackoverflow.com/questions/185931/weakreference-and-event-handling – fostandy

+13

पोस्टरिटी के लिए नोट: शून्य के संदर्भ को सेट करना कचरा कलेक्टर को केवल एक पंक्ति के विस्तार से खर्च कर देता है संदर्भ। .NET वीबी 6 नहीं है। –

उत्तर

172

विशिष्ट प्रश्न के लिए "कचरा एकत्र किया जा pClass करेंगे": घटना सदस्यता pClass के संग्रह पर कोई प्रभाव नहीं (प्रकाशक के रूप में) है।

सामान्य रूप से जीसी के लिए (विशेष रूप से, लक्ष्य): यह निर्भर करता है कि MyFunction स्थिर या उदाहरण-आधारित है या नहीं।

एक उदाहरण विधि में एक प्रतिनिधि (जैसे एक ईवेंट सदस्यता) उदाहरण के संदर्भ में शामिल है। तो हाँ, एक घटना सदस्यता जीसी को रोक देगा। हालांकि, जैसे ही ऑब्जेक्ट प्रकाशित करने वाला ऑब्जेक्ट (उपरोक्त पी क्लास) संग्रह के लिए योग्य है, यह एक समस्या बन जाती है।

ध्यान दें कि यह एक तरफा है; यानी अगर हमने:

publisher.SomeEvent += target.SomeHandler; 

फिर "प्रकाशक" "लक्ष्य" जिंदा है, लेकिन 'लक्ष्य' रखने नहीं होगा "प्रकाशक" जीवित रखेंगे।

तो नहीं: यदि पी क्लास को एकत्रित किया जा रहा है, तो श्रोताओं की सदस्यता समाप्त करने की कोई आवश्यकता नहीं है। हालांकि, यदि पी क्लास लंबे समय तक रहता था (माईफंक्शन के साथ उदाहरण से अधिक लंबा), तो पी क्लास उस उदाहरण को जीवित रख सकता है, इसलिए यदि सदस्यता को एकत्रित करना चाहते हैं तो सदस्यता समाप्त करने के लिए आवश्यक हो।

स्थिर कारण, हालांकि, इस कारण से, उदाहरण-आधारित हैंडलर के साथ उपयोग किए जाने पर बहुत खतरनाक होते हैं।

+0

धन्यवाद, यही मुझे संदेह है। –

+5

ठीक है, अगर सवाल है "क्या पी क्लास संग्रहित कचरा होगा", तो उत्तर "यह निर्भर करता है कि ..." वास्तव में सही नहीं है। यह किसी भी चीज़ पर निर्भर नहीं है, क्योंकि मार्क स्वयं आगे नोट करता है। –

+0

@ टोर - पर्याप्त मेला - मैं –

5

हां, पी क्लास एकत्र कचरा होगा। घटना सदस्यता का अर्थ यह नहीं है कि पीएलसीएएस के लिए कोई संदर्भ मौजूद है।

ऐसा नहीं, पीसीएलएएस को कचरा इकट्ठा करने के लिए आपको हैंडलर को अलग नहीं करना पड़ेगा।

6

पल का एक टुकड़ा अब संदर्भित नहीं है, यह कचरा संग्रह के लिए उम्मीदवार बन जाता है। जब आपकी कक्षा का उदाहरण गुंजाइश से बाहर हो जाता है, तो अब आपके प्रोग्राम द्वारा संदर्भित नहीं किया जाता है। अब इसका उपयोग नहीं किया जाता है और इसलिए सुरक्षित रूप से एकत्र किया जा सकता है।

यदि आप सुनिश्चित नहीं हैं कि कुछ गीला हो जाएगा तो आपसे निम्नलिखित प्रश्न पूछें: क्या अभी भी इसका संदर्भ मौजूद है? ईवेंट हैंडलर को ऑब्जेक्ट इंस्टेंस द्वारा संदर्भित किया जाता है, न कि दूसरी तरफ।

0

pClass कचरा इकट्ठा किया जाएगा। हालांकि, यदि उपरोक्त कोड स्निपेट किसी अन्य वर्ग के अंदर है, तो उस वर्ग का उदाहरण साफ़ नहीं किया जा सकता है यदि आप pClassnull पर सेट नहीं करते हैं।

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