2009-03-05 11 views
17

यदि .NET में कचरा संग्रह है तो आपको स्पष्ट रूप से IDisposable क्यों कॉल करना होगा?के लिए IDisposable क्या है?

+2

यदि आप खोज बॉक्स में आईडीस्पोजेबल डालते हैं तो इस प्रश्न के कई मौजूदा उत्तर हैं। –

उत्तर

46

कचरा संग्रह स्मृति के लिए है। आपको गैर-मेमोरी संसाधनों का निपटान करने की आवश्यकता है - फ़ाइल हैंडल, सॉकेट, जीडीआई + हैंडल, डेटाबेस कनेक्शन इत्यादि। आमतौर पर IDisposable प्रकार का अंडरलाइज़ होता है, हालांकि असली हैंडल संदर्भों की श्रृंखला के नीचे काफी लंबा रास्ता हो सकता है। उदाहरण के लिए, आप DisposeXmlWriter का उपयोग कर सकते हैं जो StreamWriter का निपटारा करता है, जिसमें इसका संदर्भ है, जो FileStreamको का संदर्भ देता है, जो संदर्भ को फ़ाइल संभालता है।

5

क्योंकि ऑब्जेक्ट्स में कभी-कभी स्मृति के बगल में संसाधन होते हैं। जीसी स्मृति जारी करता है; IDISposable है ताकि आप कुछ और जारी कर सकते हैं।

1

क्योंकि आप नियंत्रण करना चाहते हैं जब आपके ऑब्जेक्ट द्वारा बनाए गए संसाधन साफ़ हो जाएंगे।

देखें, जीसी काम करता है, लेकिन ऐसा लगता है जब ऐसा लगता है, और फिर भी, आपके ऑब्जेक्ट्स में जो फाइनलर्स आप जोड़ते हैं उन्हें केवल 2 जीसी संग्रह के बाद ही कॉल किया जाएगा। कभी-कभी, आप उन वस्तुओं को तुरंत साफ करना चाहते हैं।

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

उदाहरण संसाधन जिन्हें आप तुरंत साफ़ करना चाहते हैं वे हैं: डेटाबेस हैंडल, फ़ाइल हैंडल, नेटवर्क हैंडल।

8

अन्य टिप्पणी पर थोड़ा विस्तार करना:

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

हालांकि, कुछ अन्य बातों को ध्यान में रखना:।

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

    Implementing a Dispose Method

    Or read that whole section of MSDN on Garbage Collection

+0

पुन: "IDISposable लागू न करें ... जब तक आपको पूरी तरह से आवश्यकता नहीं है" - इंटरफ़ेस को परिभाषित करते समय सावधान रहें- अगर इंटरफ़ेस के कार्यान्वयन के लिए निपटान की आवश्यकता हो सकती है तो इंटरफ़ेस को शुरुआत से अपरिहार्य होना चाहिए। अन्यथा सभी ग्राहकों को रिफैक्टरिंग की आवश्यकता होगी। अच्छे और अधिक गहन उत्तर के लिए – morechilli

+0

+1। मुझे संदेह है कि कुछ लागू नहीं करने के बारे में चेतावनी जब तक आपको 'निपटान() 'की तुलना में' अंतिमकरण()' पर अधिक निर्देशित नहीं किया जाता है। –

+0

'आईडीस्पोजेबल' का उद्देश्य ऑब्जेक्ट्स को जानने की मानक माध्यम प्रदान करना है जब उनकी सेवाओं की आवश्यकता नहीं होती है। यह बदले में उन्हें अन्य वस्तुओं को सूचित करने की अनुमति देता है जिनकी सेवाओं का उपयोग वे कर रहे थे कि उन अन्य वस्तुओं की सेवाओं की अब आवश्यकता नहीं है। ऑब्जेक्ट्स जो उनकी सेवाओं की आवश्यकता नहीं है, उन्हें 'आईडीस्पोजेबल' लागू करना चाहिए। ऑब्जेक्ट्स जिनके पास अन्य ऑब्जेक्ट्स हैं, जिनकी परवाह नहीं है, उन्हें अब भी 'आईडीस्पोजेबल' लागू करना चाहिए, ताकि वे उन आंतरिक वस्तुओं को "अब आवश्यक नहीं" अधिसूचनाएं अग्रेषित कर सकें। – supercat

0

IDisposable इंटरफेस अक्सर संसाधनों के संदर्भ में वर्णित है, लेकिन इस तरह के अधिकांश विवरण वास्तव में "संसाधन" का क्या अर्थ है इस पर विचार करने में विफल रहते हैं।

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

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

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

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