2008-09-22 13 views
5

दृश्य स्टूडियो में, जब मैं लाइन "Implements IDisposable" टाइप करें, आईडीई स्वचालित रूप से जोड़ता है:वीबीएनईटी - आईडीआईएसओपेबल को लागू करते समय एक अंतिम विधि जोड़ा जाना चाहिए?

  • एक disposedValue सदस्य चर
  • एक Sub Dispose() Implements IDisposable.Dispose
  • एक Sub Dispose(ByVal disposing As Boolean)

Dispose() होना चाहिए अकेले छोड़ दिया, और साफ अप कोड Dispose(disposing) में रखा जाना चाहिए।

हालांकि Dispose Finalize Pattern कहता है कि आपको Dispose(False) पर कॉल करने के लिए Sub Finalize() ओवरराइड करना चाहिए। आईडीई भी यह क्यों नहीं जोड़ता है? क्या मुझे इसे स्वयं जोड़ना चाहिए, या इसे किसी तरह से बुलाया जाना चाहिए?

संपादित करें: कोई विचार क्यों आईडीई स्वचालित रूप से आवश्यक सामग्री का 80% जोड़ता है लेकिन अंतिम विधि को छोड़ देता है? इन चीजों को भूलने में आपकी सहायता के लिए इस तरह की सुविधा का पूरा बिंदु नहीं है?

EDIT2: आपके उत्कृष्ट उत्तरों के लिए धन्यवाद, अब यह सही समझ में आता है!

उत्तर

11

यदि आप वास्तव में गैर-प्रबंधित संसाधन धारण कर रहे हैं जो स्वचालित रूप से कचरा कलेक्टर द्वारा साफ नहीं किया जाएगा और आपके निपटान() में सफाई कर रहे हैं, तो हाँ, आपको इसे अंतिम रूप() में करना चाहिए।

यदि आप किसी अन्य कारण से आईडीस्पोज़ेबल लागू कर रहे हैं, तो कार्यान्वित करना() की आवश्यकता नहीं है।

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

+1

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

+1

यह गलत है।यदि आप अप्रबंधित संसाधनों को मुक्त करने के लिए पूरी तरह से निपटान() पर भरोसा करते हैं, तो स्मृति उन मामलों में रिसाव होगी जहां निपटान नहीं कहा जाता है। यही वही है जो फाइनलाइज़र के लिए है। – Laurent

+1

यह सुनिश्चित नहीं है कि मैंने पहले स्कॉट की टिप्पणी क्यों नहीं छोड़ी थी - इसे ध्यान में नहीं देखा होगा, लेकिन लॉरेन सही है - यदि आपका निपटान अप्रबंधित संसाधनों की सफाई कर रहा है, तो सुरक्षा के लिए अंतिम रूप देना आवश्यक है। इसे छोड़ दो क्योंकि तुम आलसी हो। –

3

नहीं, आपको तब तक अंतिम रूप देने की आवश्यकता नहीं है जब तक आपके पास साफ करने के लिए अप्रबंधित संसाधन न हों।

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

+0

आप कभी भी फाइनेंजर की आवश्यकता के बिना एक निपटान विधि में अप्रबंधित संसाधनों को मुक्त कर सकते हैं। –

+0

आप कर सकते हैं, लेकिन यदि निपटान नहीं किया जाता है तो आप शायद अंतिम विधि के बिना स्मृति को रिसाव करेंगे। –

1

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

मैंने fairly long blog post को कुछ समय पहले आईडीस्पोजेबल और फाइनलाइजर्स के पृष्ठभूमि और कार्यान्वयन को कवर किया, जो पढ़ने के लायक हो सकता है यदि आप इसके बारे में बिल्कुल स्पष्ट नहीं हैं।

+0

आप कभी भी अंतिम रूप देने की आवश्यकता के बिना एक निपटान विधि में अप्रबंधित संसाधनों को मुक्त कर सकते हैं। –

+0

वैसे हाँ, यह IDisposable पैटर्न का पूरा बिंदु है। हालांकि अगर लोग निपटान करना भूल जाते हैं तो फाइनलज़र एक सुरक्षा है जो उन्हें अंततः साफ कर देता है, जिसे इस बारे में भुलाया नहीं जा सकता क्योंकि इसे रनटाइम द्वारा बुलाया जाता है। –

2
Implements IDisposable 

Public Overloads Sub Dispose() Implements IDisposable.Dispose 

    Dispose(True) 
    GC.SuppressFinalize(Me) 

End Sub 

Protected Overloads Sub Dispose(ByVal disposing As Boolean) 

    If disposing Then 
     ' Free other state (managed objects). 
    End If 
    ' Free your own state (unmanaged objects). 
    ' Set large fields to null. 
End Sub 

Protected Overrides Sub Finalize() 

    Dispose(False) 
    MyBase.Finalize() 

End Sub 
+3

कोड का एक स्लैब बहुत उपयोगी नहीं है। प्रदान किए गए कोड के पीछे एक छोटे से विवरण और तर्क के साथ, अधिक रचनात्मक होने का प्रयास करें। –

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