2013-05-17 12 views
15

this answer मैंने पाया में,निपटान()?

सफाई अंतिम रूप विधि में अप्रबंधित संसाधनों और निपटान विधि में कामयाब रहे हैं, जब निपटान/अंतिम रूप पैटर्न अपने कोड में इस्तेमाल किया गया है।

और बाद में मुझे अंतिम रूप देने और निपटाने के बारे में this nice article मिला और उनके बारे में एक स्पष्ट विचार मिला।

class Test : IDisposable 
{ 
    private bool isDisposed = false; 

    ~Test() 
    { 
     Dispose(false); 
    } 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      // Code to dispose the managed resources of the class 
     } 
     // Code to dispose the un-managed resources of the class 

     isDisposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

लेकिन वह नीचे, एक ही नोट (जो मैं इस सवाल की शुरुआत में शामिल है) प्रकट होता है: लेख निम्नलिखित कोड (पेज 3), अवधारणाओं की व्याख्या करने के है।

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

अब मैं उलझन में हूं। पूरे लेख में और कोड नमूने में, यह दिखाया गया है कि अप्रबंधित संसाधनों को Dispose() में मुक्त किया जाना चाहिए। लेकिन फिर उस टिप्पणी की प्रासंगिकता क्या है?

संपादित करें:

यह पुष्टि की है के रूप में है कि इस लाइन:,

सीधे शब्दों में अंतिम रूप विधि में डाल दिया, सफाई अप्रबंधित संसाधनों और कामयाब लोगों निपटान विधि में जब निपटान/अंतिम रूप पैटर्न अपने कोड

गलत है, मैं this answer संपादित में इस्तेमाल किया गया है।

उत्तर

30

इसे बहुत आसान देखें।

  1. आप अप्रबंधित संसाधनों के साथ काम कर रहे हैं, तो - लागू दोनों निपटान और अंतिम रूप।डेवलपर्स द्वारा संसाधनों को मुक्त करने के लिए जल्द ही संसाधनों को मुक्त करने के लिए कहा जाना चाहिए कि उन्हें अब इसकी आवश्यकता नहीं है। अगर वे निपटान को कॉल करना भूल जाते हैं तो फ्रेमवर्क अपने जीसी चक्र में अंतिम रूप देने को कॉल करता है (आमतौर पर अपना खुद का मीठा समय लेगा)।
  2. यदि आप अप्रबंधित संसाधनों से निपट नहीं रहे हैं - तब कुछ भी न करें। कार्यान्वित न करें और न ही निपटान करें।
  3. अपने वस्तु डिस्पोजेबल वस्तुओं आंतरिक का उपयोग करता है - आप को लागू निपटान() अगर आपने बनाया है और एक प्रकार है जो निपटान() को लागू करता है और जो आप पहले से ही निपटारा नहीं किया है की किसी भी वस्तु के लिए एक संदर्भ को बनाए रखा।

कुछ क्लासिक उदाहरण:

System.IO.FileStream वस्तु लॉक/स्ट्रीम फ़ाइलों को संभालती प्रबंधन करता है। तो यह दोनों निपटान और अंतिम रूप लागू करता है। यदि डेवलपर इसे निपटाता है तो दूसरा प्रोग्राम इसे तुरंत एक्सेस कर सकता है। अगर वह इसे निपटाना भूल जाता है तो फ्रेमवर्क इसे अंतिम रूप देता है और बाद में अपने जीसी चक्र में हैंडल बंद करता है।

सिस्टम.Text.StringBuilder खुराक में कोई अप्रबंधित संसाधन नहीं है। इसलिए कोई अंतिम रूप देने का कोई निपटान नहीं है।

जहां तक ​​पैटर्न का सवाल है क्या यह
// Code to dispose the managed resources of the class
करने का मतलब है कि फोन है तो आप उस वर्ग

और

// Code to dispose the un-managed resources of the class साधन के अंदर घटक के रूप में है कि किसी भी नेट वस्तुओं के निपटान के तरीकों कच्चे हैंडल और पॉइंटर्स बंद करें। यहाँ, यह

class Test : IDisposable 
    { 
    private bool isDisposed = false; 

    ~Test() 
    { 
     Dispose(false); 
    } 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
     // Code to dispose the managed resources of the class 
     internalComponent1.Dispose(); 
     internalComponent2.Dispose(); 
     } 

     // Code to dispose the un-managed resources of the class 
     CloseHandle(handle); 
     handle = IntPtr.Zero; 

     isDisposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    } 

यहाँ उदाहरण के साथ अपने अपडेट किए गए कोड एक पुराने सवाल यह explaing http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/186947fd-e6da-41fb-9998-3b1e6223f17c

+0

वास्तव में प्रबंधित संसाधनों की कोई सफाई नहीं है। मैं किसी भी तरह से अपने बिंदु को प्रासंगिक नहीं देखता हूं। एक प्रबंधित संसाधन को साफ़ करने के लिए आप जो अधिकतम कर सकते हैं वह इसे पूर्ण करने के लिए है। जो कि –

+0

में निर्मित एक अच्छे जीसी के साथ पूरी तरह से अनावश्यक है, 2006 में लिखा गया एक लेख है, इसलिए मैं वास्तव में इसके बारे में ज्यादा परेशान नहीं करता। –

+2

यह काफी आसान नहीं है। आपको 'निपटान()' को भी लागू करना चाहिए यदि आपने किसी प्रकार के * किसी * ऑब्जेक्ट का संदर्भ बनाया और बनाए रखा है जो 'निपटान()' लागू करता है और जिसे आपने पहले ही डिस्पोजेक्ट नहीं किया है। कुछ प्रकार अप्रबंधित संसाधनों का उपयोग नहीं करते हैं, लेकिन उनके पास ऐसी घटनाओं के लिए सदस्यता जैसे चीजें हैं जिन्हें उन्हें अपने 'निपटान()' विधियों में अनदेखा करना चाहिए। आपको ऐसी वस्तुओं का निपटान करना चाहिए जब भी वे अप्रबंधित संसाधनों का उपयोग नहीं करते हैं, अन्यथा आपके पास एक प्रकार की मेमोरी रिसाव हो सकती है। यह अक्सर 'नियंत्रण' या 'UserControl' से प्राप्त UI कक्षाओं के लिए विशेष रूप से सच है। –

3

एक Foo संसाधनों जो नियतात्मक सफाई से लाभ होगा है, लेकिन कोई भी है कि उपयोगी एक finalizer में साफ किया जा सकता है IDisposable को कार्यान्वित करना चाहिए, लेकिन Finalize को ओवरराइड नहीं करना चाहिए या विनाशक होना चाहिए। यदि किसी वर्ग में कई संसाधन होते हैं, और कम से कम एक को अंतिम रूप में साफ किया जा सकता है, तो प्रत्येक पृथक संसाधन जिसे अंतिम रूप में साफ किया जा सकता है उसे अपने स्वयं के अंतिम/विनाशक-सुसज्जित वस्तु (जिसे परिभाषित किया जा सकता है) में समझाया जाना चाहिए संरक्षित नेस्टेड वर्ग), और उस वर्ग में शामिल वर्गों में रैपर ऑब्जेक्ट्स के संदर्भ होना चाहिए। एक बार ऐसा करने के बाद, बाहरी कक्षा Dispose विधि वाले कक्षाओं के पैटर्न के अनुरूप होगी लेकिन कोई फाइनलाइज़र/विनाशक नहीं होगा।

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