2009-02-09 13 views
5

मुझे पता है कि जब आप किसी ऑब्जेक्ट को माउस के संलग्न ईवेंट में पंजीकृत करते हैं, तो आपके पास मेमोरी लीक होती है। यही कारण है कि आपको WeakEvent pattern का उपयोग करने की आवश्यकता है।कैसे अंतर्निहित WPF नियंत्रण अपने ईवेंट हैंडलर को एक संलग्न ईवेंट में प्रबंधित करते हैं?

मुझे इस पैटर्न के साथ कोई समस्या है: यदि आप इसका उपयोग करना चाहते हैं, तो आप XAML कोड में अपने हैंडलर को परिभाषित नहीं कर सकते हैं।

मेरे लिए, इसका मतलब है कि इस तरह से हर कोड लीक:

<SomeControl Mouse.MouseDown="MyHandler" /> 

जब तक आप कोड में स्पष्ट रूप से अपने प्रबंधक को निकाल (और मुझे संदेह है कि कोई भी व्यक्ति उस करता है)। अब वहाँ कुछ मुझे समझ नहीं आता है:

<Button Click="MyHandler" /> 

इस कोड को किसी भी तरह कहीं बटन पर क्लिक पता लगाने के लिए Mouse.MouseDown घटना का उपयोग करें। परावर्तक के साथ कुछ शोध के साथ, मैंने पाया कि यह घटना UIElement क्लास के माउसडाउन का उपयोग करती है। और जब मैं UIElement के कोड को पढ़ता हूं तो मुझे समझ में नहीं आ रहा है: कोई WeakEventManager नहीं है!

क्या कोई मुझे बता सकता है कि UIElement माउस से घटनाओं को कैसे प्राप्त करता है। रिसाव के बिना माउसडाउन?

उत्तर

7

एक्सएएमएल में सामान्य हैंडलर का उपयोग कमजोर संदर्भों की आवश्यकता नहीं है।

आप जो कर रहे हैं वह मुख्य नियंत्रण और इस नियंत्रण में निहित बाल नियंत्रण के बीच स्मृति संदर्भ बना रहा है; इस मामले में बाल नियंत्रण बटन है।

यदि कोई मुख्य नियंत्रण के लिए दृश्य पेड़ के किसी भी भाग का संदर्भ रखता है, तो पूरा पेड़ स्मृति में रहेगा क्योंकि यह एक साथ जुड़ा हुआ है (माता-पिता/बाल संदर्भ)।

अब अगर इस पेड़ के सभी संदर्भ हटा दिए गए हैं, तो माता-पिता और बच्चे (मुख्य नियंत्रण और बटन) के बीच ईवेंट संदर्भ महत्वपूर्ण नहीं है क्योंकि ये नियंत्रण पहले से ही माता-पिता/बाल संदर्भों से जुड़े हुए थे। एक बार सभी बाहरी संदर्भ हटा दिए जाने के बाद, यह नियंत्रण कचरा इकट्ठा किया जा सकता है।

एक्सएएमएल के भीतर इवेंट हैंडलर केवल आंतरिक ईवेंट संदर्भ बनाते हैं।

बाहरी ग्राहकों को नियंत्रण पर किसी ईवेंट पर पंजीकरण करते समय सावधान रहना होगा, क्योंकि आप बाहरी संदर्भ बना रहे हैं जो लिंक और क्लाइंट मौजूद होने तक नियंत्रण को तब तक जीवित रखेगा जब तक कि यह एक कमजोर संदर्भ न हो) ।

आपका प्रश्न संलग्न घटनाओं के बारे में है। संलग्न घटनाएं मेमोरी लीक का कारण बनती हैं या नहीं, इस पर कोई स्पष्ट दस्तावेज नहीं दिखता है। यह मुझे यूआई नियंत्रण की तरह दिखता है जो घटना की सदस्यता लेता है, इसके बजाए घटना के संदर्भ में अन्य संदर्भों के बजाय संदर्भ होता है, लेकिन मुझे लगता है कि स्थैतिक ईवेंट ऑब्जेक्ट को उस नियंत्रण को सूचित करने का कोई तरीका होना चाहिए जिसे इसे निकाल दिया गया है। माइक्रोसॉफ्ट से इस पर टिप्पणी की एक आश्चर्यजनक कमी प्रतीत होती है।

+0

मैं आपके साथ सहमत हूं, हालांकि XAML में एक अटैचमेंट ईवेंट में हैंडलर (मैं नियंत्रण 'घटनाओं के बारे में बात नहीं करता हूं लेकिन माउस.माउसडाउन के रूप में ईवेंट) रिसाव कर सकता है, क्योंकि इसमें हमेशा एक संदर्भ होता है। आंतरिक रूप से, बटन क्लास माउस का उपयोग करता है। माउसडाउन ईवेंट (UIElement विशिष्ट होना) और मुझे नहीं पता कि यह क्यों रिसाव नहीं करता है। –

+0

अच्छा बिंदु। संलग्न घटनाएं बाहरी संदर्भ हैं। –

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