2009-10-11 21 views
20

का उचित सफाई मैं WPF के लिए अपेक्षाकृत नया हूं, और इसके साथ कुछ चीजें मेरे लिए काफी विदेशी हैं। एक के लिए, विंडोज फॉर्म के विपरीत, डब्ल्यूपीएफ नियंत्रण पदानुक्रम IDisposable का समर्थन नहीं करता है। विंडोज प्रपत्रों में, यदि कोई उपयोगकर्ता नियंत्रण किसी भी प्रबंधित संसाधन का उपयोग करता है, तो प्रत्येक नियंत्रण को लागू करने वाले निपटान विधि को ओवरराइड करके संसाधनों को साफ करना बहुत आसान था।WPF उपयोगकर्ता नियंत्रण

डब्ल्यूपीएफ में, कहानी इतना आसान नहीं है। मैंने कई घंटों तक इसकी खोज की है, और दो बुनियादी विषयों का सामना किया है:

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

दूसरा, मुझे डिस्पैचर के कुछ संदर्भ मिले। ShutdownStarted। मैंने शट डाउनस्टार्ट ईवेंट का उपयोग करने की कोशिश की है, लेकिन यह हर नियंत्रण के लिए आग लगती नहीं है। मेरे पास WPF UserControl का एक गुच्छा है कि मैंने शट डाउनस्टार्ट के लिए एक हैंडलर लागू किया है, और इसे कभी भी कॉल नहीं किया जाता है। मुझे यकीन नहीं है कि यह केवल विंडोज़, या शायद डब्ल्यूपीएफ ऐप क्लास के लिए काम करता है। हालांकि यह ठीक से फायरिंग नहीं है, और जब भी ऐप बंद हो जाता है तो मैं खुले प्रदर्शन काउंटर ऑब्जेक्ट्स को लीक कर रहा हूं।

वहाँ Dispatcher.ShutdownStarted घटना से अप्रबंधित संसाधनों को साफ करने के लिए एक बेहतर विकल्प है? क्या IDISposable को लागू करने के लिए कुछ चाल है कि निपटान कहा जाएगा? यदि संभव हो तो मैं से फ़ाइनलइज़र का उपयोग करके अधिक पसंद करूंगा।

उत्तर

12

मुझे डर है कि Dispatcher.ShutdownStarted वास्तव में केवल तंत्र WPF UserControls में संसाधनों के निपटान के लिए प्रदान करता होने लगते है हूँ। (एक बहुत पहले similar question देखें मैंने कुछ समय पहले पूछा था)।

समस्या दृष्टिकोण एक और तरीका है (जब MVVM पद्धति का उपयोग कर इस तरह के ViewModel के रूप में) अपने डिस्पोजेबल संसाधनों के सभी (बिल्कुल संभव हो तो) के पीछे कोड से बाहर है और अलग वर्गों में स्थानांतरित करने के लिए है। फिर एक उच्च स्तर पर आप अपनी मुख्य विंडो को बंद कर सकते हैं और मैसेंजर क्लास के माध्यम से सभी व्यू मॉड्यूल को सूचित कर सकते हैं।

मुझे आश्चर्य है कि आपको डिस्पैचर नहीं मिला है। शट डाउनस्टार्ट ईवेंट। क्या आपके UserControls उस समय शीर्ष-स्तरीय विंडो से जुड़े हुए हैं? क्योंकि तंत्र Winforms से अलग है

+4

+1 कोडबेंड से बाहर डिस्पोजेबल संसाधनों को स्थानांतरित करने के लिए +1। डब्ल्यूपीएफ के लिए प्रमुख सीखने के बिंदुओं में से एक डेटाबेसबेस आर्किटेक्चर की ताकत और अभिव्यक्ति का लाभ उठाने के लिए कोडबेइंड को कम कर रहा है। यह सीखने के लिए एक दर्दनाक बात है (सीखने की अवस्था एक चट्टान पर चढ़ने की तरह अधिक है), लेकिन जब आप विचार के डब्ल्यूपीएफ मोड को "प्राप्त" करते हैं तो पुरस्कृत होता है। –

+0

सभी डिस्पोजेबल संसाधन वास्तव में व्यूमोडेल में हैं, जो स्वयं ही पहचान योग्य हैं। मैं वास्तव में उलझन में हूं कि डिस्पैचर.शूटडाउनस्टार्ट घटना क्यों फायरिंग नहीं कर रही है। प्रदर्शन काउंटर कंट्रोल (और इसके संबंधित व्यूमोडेल) वास्तव में डब्ल्यूपीएफ ग्राफ से जुड़े हुए हैं क्योंकि यह में में एम्बेडेड है। – jrista

+1

@ ग्रेग डी: मुझे आमतौर पर डब्ल्यूपीएफ मॉडल मिलता है। जैसे ही मैंने डब्ल्यूपीएफ की मूलभूत बातें हासिल की थी, मैंने एमवीवीएम का उपयोग करना शुरू कर दिया था, और मेरा कोडबिहेंड उतना ही उतना ही बेकार है जितना इसे प्राप्त होता है (बस डिफ़ॉल्ट कन्स्ट्रक्टर और इसके कॉल को प्रारंभिक कॉम्पोनेंट)। डब्ल्यूपीएफ की कंपोज़ेबिलिटी और डाटाबेसिंग क्षमताओं आश्चर्यजनक से परे हैं, और यदि मेरे पास विकल्प है तो मैं कभी भी विंडोज फॉर्म पर वापस नहीं जाऊंगा। – jrista

9

IDisposable इंटरफ़ेस, (लगभग) WPF के तहत कोई अर्थ नहीं है। डब्ल्यूपीएफ में, आपको दृश्य और तार्किक पेड़ को ध्यान में रखना चाहिए: यह मौलिक है।
तो, कोई भी दृश्य वस्तु आम तौर पर किसी अन्य वस्तु के बच्चे के रूप में रहता है। डब्ल्यूपीएफ बिल्डिंग तंत्र का आधार विज़ुअल ऑब्जेक्ट को पदानुक्रमित रूप से संलग्न करना है, फिर जब वे उपयोगी नहीं होते हैं तो उन्हें अलग करें और नष्ट करें।

मुझे लगता है कि आप UIElement के बाद से उजागर विधि को देख सकते हैं: इस विधि को या तो दृश्य वस्तु संलग्न होने पर और अलग होने पर कहा जाता है। अप्रबंधित वस्तुओं (सॉकेट, फाइल इत्यादि) का निपटान करने के लिए यह सही जगह हो सकती है।

+0

OnVisualParentChanged के बारे में टिप के लिए धन्यवाद। मैं इसके साथ खेलूँगा और देख सकता हूं कि यह मेरी समस्या को हल करने में मदद करता है या नहीं। – jrista

0

अन्य लोगों को इस समस्या के बारे में वास्तव में उपयोगी जानकारी दी है, वहीं आपको लगता है कि नहीं हो सकता है कि क्यों कोई IDisposable है एक बहुत समझाता जानकारी का एक छोटा सा है। असल में, डब्ल्यूपीएफ (और सिल्वरलाइट) कमजोर संदर्भों का भारी उपयोग करता है - यह आपको उस वस्तु का संदर्भ देने की अनुमति देता है जिसे जीसी अभी भी एकत्र कर सकता है।

+0

अंतर्दृष्टि पीट के लिए धन्यवाद। मैं उत्सुक हूं यदि आपके पास कुछ लिंक हैं जो इसे अधिक विस्तार से समझाते हैं? मैं उत्सुक हूं कि वीक संदर्भों का भारी उपयोग समस्याओं का कारण नहीं बनता है। वे विशिष्ट स्थितियों में एक शक्तिशाली उपकरण हो सकते हैं ... लेकिन मैं कल्पना नहीं कर सकता कि उनका उपयोग WPF में कैसे किया जाता है। – jrista

5

मैं यह भी के लिए और विभिन्न विकल्पों का परीक्षण करने के बाद देख रहा था मैं Venezia

protected override void OnVisualParentChanged(DependencyObject oldParent) 
    { 
     if (oldParent != null) 
     { 
      MyOwnDisposeMethod(); //Release all resources here 
     } 

     base.OnVisualParentChanged(oldParent); 
    } 

का समाधान लागू मैंने महसूस किया कि जब माता पिता कॉल Children.Clear() विधि और पहले से ही आइटम बच्चे को जोड़ा गया था, DependencyObject एक मूल्य था। लेकिन जब माता-पिता ने एक आइटम जोड़ा (Children.Add(CustomControl)) और बच्चे खाली थे निर्भरता ऑब्जेक्ट शून्य था।

+0

मैंने इसे बदल दिया है (माता-पिता == शून्य) ताकि अगर मैं नियंत्रण को एक अलग कंटेनर में ले जाऊं, तो यह स्वयं को नष्ट नहीं करेगा – Sean

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