2012-04-11 10 views
5

उदाहरण के लिए मैं एक विधिAutodisposing वस्तुओं

SomeMethod(Graphics g) 
{ 
    ... 
} 

है, तो मैं एक तरीके से इस विधि कॉल करेंगे

SomeMethod(new Graphics()) 

मेरी ग्राफिक्स autodisposed जा आपत्ति होगी या मैं के अंत में मैन्युअल g.Dispose() बुलाना चाहिए प्रक्रिया?

SomeMethod(Graphics g) 
{ 
    ... 
    g.Dispose(); 
} 
+4

'नहीं' के अतिरिक्त, आपकी विधि ग्राफिक्स ऑब्जेक्ट का निपटान करने के लिए भी * जिम्मेदार नहीं होना चाहिए। यह महत्वपूर्ण है कि ग्राफिक्स ऑब्जेक्ट्स को एक ही स्थान पर प्रबंधित किया जाए - जिसका अर्थ है कि इसे उसी वर्ग में डिस्पोजेड किया जाना चाहिए जिसने इसे बनाया है। कॉल स्टैक के नीचे कुछ अनिश्चित जगह में ऑब्जेक्ट का निपटारा करने के लिए कोड को समझने और बनाए रखने में कठिनाई होती है, और आसानी से बाद में त्रुटियों का कारण बन सकती है। – MattDavey

उत्तर

7

डिस्पोजेबल वस्तुओं autodisposed नहीं मिलेगा (निकटतम वे कहते हैं कि करने के लिए प्राप्त कर सकते हैं एक finalizer कि Dispose यदि आवश्यक हो तो कॉल लागू कर रहा है)। आपको Dispose() पर कॉल करके या using ब्लॉक के साथ इसका उपयोग करके मैन्युअल रूप से ऐसा करना होगा।

आप ऑटो वस्तु निपटान के लिए चाहते हैं, आप ऐसा कर सकता है:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

ब्लॉक का उपयोग सुनिश्चित करता है कि Dispose() प्रक्रिया स्वतः ही कहा जाता है ब्लॉक समाप्त होता है (इसलिए इस मामले में जैसे ही, SomeMethod के बाद रिटर्न या अपवाद फेंकता है)।

नोट: यदि संभव हो तो आपको उस स्थान पर ऑब्जेक्ट का निपटान करना चाहिए जहां आपने इसे बनाया था। एक वैध वस्तु में लेना और विधि के अंदर इसका निपटान भ्रम पैदा कर सकता है।

ग्राफिक्स और शायद अधिकांश यदि इस इंटरफ़ेस को लागू करने वाले सभी बीसीएल वर्ग भी Dispose() को कॉलिज़र कहलाते हैं तो कॉल करेंगे। यह IDisposable के उचित कार्यान्वयन का हिस्सा है। हालांकि आप कभी नहीं जानते कि फाइनलाइज़र कहलाता है और आपको इस क्रियान्वयन के विस्तार पर भरोसा नहीं करना चाहिए यदि आपको अपने ऑब्जेक्ट को निश्चित रूप से निपटाने के लिए आवश्यक है।

+1

उपरोक्त मेरे उदाहरण में, क्या ग्राफिक्स ऑब्जेक्ट ऑटोोडिज्ड होगा या नहीं? –

+0

नहीं। मेरा संपादन देखें। – Botz3000

+0

रुको, क्या आप कह रहे हैं कि ऑब्जेक्ट को अंतिम रूप देने पर जीसी कॉल 'डिसपोज' कॉल नहीं करेगा? ('IDisposable' के सही कार्यान्वयन को देखते हुए) – leppie

3

आप शायद, एक का उपयोग कर बयान

using (var graphicsObject = new Graphics()) { 
    SomeMethod(graphicsObject); 
} 

वस्तु स्वचालित रूप से कथन का उपयोग के अंत में निपटारा किया जाएगा का उपयोग करना चाहिए एक अपवाद तब होता है, भले ही।

2

चेक Graphics Class

public sealed class Graphics : MarshalByRefObject, 
    IDeviceContext, IDisposable 

यह IDisposable इंटरफ़ेस लागू करता है, इसलिए यदि आप वस्तु में ग्राफिक्स के साथ using कथन का उपयोग यह स्वचालित रूप से निपटाया जाएगा।

अपने उदाहरण में

SomeMethod(Graphics g) 
     { 
     ... 
     g.Dispose(); 
     } 

यह g.Dispose का उपयोग कर निपटारा किया जाएगा, लेकिन सबसे अच्छा अभ्यास using बयान है।

उदाहरण:

using (Graphics g = this.CreateGraphics()) 
{ 
//Do some graphics operation. 
} 
4

डिस्पोजेबल वस्तुओं के साथ काम करने के लिए उचित तरीके से उन्हें using ब्लॉकों में रैप करने के लिए है:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

जब निष्पादन using ब्लॉक Graphics ठीक से एक है, तो भी निपटान किया जाता है छोड़ देता है अपवाद फेंक दिया गया है।

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

2

आपके उदाहरण में आपको किसी तर्क के रूप में आपको दी गई वस्तु का निपटान नहीं करना चाहिए। यह सलाह नहीं दी जाती है क्योंकि उस वस्तु का उपयोग आपकी विधि के बाहर किया जा सकता है। उपयोगिता वस्तुओं का निपटान (आमतौर पर) उसी विधि में होता है जिसे आप बनाते हैं। कक्षा व्यापक वस्तुओं या राज्य वस्तुओं के लिए अपवाद।

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

सभी .नेट फ्रेमवर्क वस्तुओं है कि तुम पर (किसी भी तरह) Dispose कॉल नहीं करते अंत में कचरा कलेक्टर द्वारा autodisposed हो जाएगी। IDisposable इंटरफ़ेस के उचित कार्यान्वयन में विनाशक/अंतिमकर्ता होना चाहिए जो Dispose पर कॉल करता है। यह सुनिश्चित करना है कि खराब कोड के कारण मूल्यवान संसाधन खो गए नहीं हैं। आपके संसाधन बहुत बाद में जारी किए जाएंगे लेकिन वे करेंगे और यह महत्वपूर्ण है। इस प्रकार .NET में सभी डिस्पोजेबल क्लासेस लागू किए गए हैं और सभी वर्गों को IDisposable को कैसे कार्यान्वित करना चाहिए। IDisposable.Dispose पद्धति पर माइक्रोसॉफ्ट की सिफारिशों के लिए

using(Graphics g = new Graphics()) 
{ 
    SomeMethod(g) 
    { 
     ... 
    } 
} 

चेक this:

आपका कोड इस तरह दिखना चाहिए।

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