2008-10-29 15 views
18

सामान्य कोड के लिए, क्या मुझे वास्तव में किसी ऑब्जेक्ट को निपटाने की आवश्यकता है? क्या मैं इसे अधिकांश भाग के लिए अनदेखा कर सकता हूं या क्या किसी ऑब्जेक्ट को हमेशा निपटाने का अच्छा विचार है जब आपका 100% सुनिश्चित करता है कि आपको अब इसकी आवश्यकता नहीं है?मुझे .NET में अपनी ऑब्जेक्ट्स का निपटान कब करना चाहिए?

उत्तर

15

यदि ऑब्जेक्ट IDISposable लागू करता है, तो आप इसे जितनी जल्दी हो सके इसका निपटान करना चाहिए। सबसे आसान तरीका है एक using ब्लॉक के साथ उसके दोनों ओर के लिए है:

using (SqlCommand cmd = new SqlCommand(conn)) { 
    cmd.ExecuteNonQuery(); 
} 
0

ज्यादातर मामलों में जीसी 'काम करता है' पर भरोसा। क्लासिक अपवाद तब होता है जब आपके पास संसाधन भारी बातचीत होती है - उस उदाहरण में स्पष्टीकरण निपटान करना सर्वोत्तम होता है।

स्पष्ट उदाहरण।

using (var conn = new SqlConnection(connString)) {} 

'उपयोग' ब्लॉक निश्चित रूप से यह सुनिश्चित करने की सबसे स्वच्छ और सबसे मजबूत विधि है कि वस्तुओं को सही तरीके से निपटाया जाता है। 'प्रयोग करना' ब्लॉक किसी भी ऑब्जेक्ट के साथ लीवरेज किया जा सकता है जो IDISposable लागू करता है।

+0

जीसी संयोग से पूरी तरह से अपने आप पर काम करता है। समय-समय पर निपटान को कॉल करने का कोई दायित्व नहीं है। – JaredPar

+0

मैंने सुझाव नहीं दिया कि जीसी को समय-समय पर ऐसा करने के लिए बाध्य किया गया था। मैं अपने दावे से खड़ा हूं कि नियमित वस्तुओं का मनोबल निपटान अनावश्यक है। – berko

+0

तो, उदाहरण के लिए, जब आप बिटमैप उदाहरण बनाते हैं, तो आपको नहीं लगता कि आपको इसे मैन्युअल रूप से निपटाने की आवश्यकता है? फिर से विचार करना। जीसी देखता है कि 30 एमबी ऑब्जेक्ट 10 बाइट्स के रूप में है और इसे अनिश्चित काल तक अनदेखा करता है। यह हर बार आपके सर्वर को दुर्घटनाग्रस्त कर देगा। –

-7

जब आप किसी ऑब्जेक्ट के साथ काम करते हैं तो आप इसके बारे में भूल सकते हैं। जब तक इसे कहीं भी संदर्भित नहीं किया जाता है तब तक यह उतना ही अच्छा होता है जितना कि चला गया। कचरा कलेक्टर इस तरह महसूस करता है जब यह स्मृति का उपयोग किया जाता है।

+0

क्या कोई बता सकता है कि इस उत्तर को इस तरह क्यों झुकाया गया था? -6? और कोई कमी नहीं है? – bobobobo

+4

@bobobobo मुझे लगता है क्योंकि यह IDisposable को संबोधित नहीं कर रहा है जिसका उद्देश्य किसी ऑब्जेक्ट को .NET रनटाइम के बाहर संसाधनों को रिलीज़ करने की अनुमति देना है जब उन्हें जीसी की प्रतीक्षा करने की आवश्यकता नहीं है। – ongle

3

इसे देखने के कुछ तरीके हैं। एक तरीका यह पता लगाने की कोशिश करता है कि क्या ऑब्जेक्ट का निपटान करने के लिए वास्तव में आवश्यक है, जैसे कि इसकी आवश्यकता नहीं है, उदाहरण के लिए रिफ्लेक्टर का उपयोग करके यह देखने के लिए कि वास्तव में अप्रबंधित संसाधनों पर है, या यदि वे संयोग से किसी भी तरह से निपटारे गए हैं। दूसरा परिप्रेक्ष्य यह मानना ​​है कि यदि कोई वस्तु IDISposable लागू करती है, तो यह निर्धारित करने के लिए आपका व्यवसाय नहीं है कि निपटान() वास्तव में कहलाए जाने की आवश्यकता है - आप हमेशा इसे कॉल करते हैं। मुझे लगता है कि जाने का सही तरीका है। ऑब्जेक्ट्स के निजी कार्यान्वयन में शामिल होने के बारे में निर्णय लेने के लिए कि आप उन्हें कैसे उपभोग कर सकते हैं, एक कार्यान्वयन के साथ मिलकर अपने जोखिम को बढ़ा सकते हैं जो बदल सकता है। एक उदाहरण LINQ से SQL DataContext है। यह IDISpose लागू करता है लेकिन अधिकतर निपटान() के लिए एक स्पष्ट कॉल की आवश्यकता के बिना खुद को साफ कर देता है। मेरी वरीयता कोड लिखना है जो स्पष्ट रूप से किसी भी तरह से निपटान करता है, लेकिन अन्य ने सुझाव दिया है कि यह आवश्यक नहीं है।

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

और जैसा कि पहले कहा गया था, (..) {...} IDISposable कार्यान्वयनकर्ताओं के लिए आपका मित्र है।

+0

यह सुनिश्चित नहीं है कि आपको यहां क्यों मतदान किया गया है। मुझसे +1 –

6

IDisposable लागू करने वाले किसी भी प्रकार पर आपको हमेशा Dispose() पर कॉल करना चाहिए, यह आमतौर पर यह इंगित करने के लिए उपयोग किया जाता है कि प्रकार अप्रबंधित संसाधन प्राप्त करता है। यह विशेष रूप से महत्वपूर्ण है कि ये मुक्त हो जाते हैं, और जितनी जल्दी हो सके। जैसा कि अन्य ने उल्लेख किया है, using ऐसा करने का पसंदीदा तरीका है।

25

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

आखिरकार जीसी मेमोरी प्रेशर महसूस करेगा और संयोग से आपके ऑब्जेक्ट को इकट्ठा करेगा (और कुछ नहीं)।यदि आप किसी निश्चित रूप से वस्तुओं का निपटान नहीं करते हैं तो लगभग कोई स्मृति दबाव वाला संसाधन भूखा राज्य दर्ज करना पूरी तरह से संभव है।

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

वास्तव में हैंडल को मुक्त करने के लिए, उदाहरणों को मुक्त करने के लिए पर्याप्त दबाव देने के लिए एक ऑपरेशन के दौरान आवंटित होने वाली स्मृति की एक बड़ी मात्रा लेनी होगी।

+0

सिस्टम। ड्रॉइंग क्लासेस मेमोरी प्रेशर के जीसी को सही तरीके से सूचित नहीं करते हैं, इसलिए उन्हें निपटान के लिए प्राथमिकता नहीं दी जाती है क्योंकि उन्हें होना चाहिए (यह 80 एमबी ऑब्जेक्ट को 1k या उससे कम के रूप में देखता है) –

1

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

0

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

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

+0

असल में, भुगतान की गई विधि कोड को दोहराना नहीं है आपकी अंतिम विधि और emthod का निपटान, लेकिन इस लिंक में विस्तृत रूप से लागू करने के लिए http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx – Sekhat

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