2009-07-30 15 views
12

आप जब की तरह कोड:कब निपटान आवश्यक है?

Bitmap bmp = new Bitmap (100, 100); 
Graphics g = Graphics.FromImage (bmp); 

Pen p = new Pen (Color.FromArgb (128, Color.Blue), 1); 
Brush b = new SolidBrush (Color.FromArgb (128, Color.Blue)); 

g.FillEllipse (b, 0, 0, 99, 99);  
g.FillRegion (b, pictureBox1.Region); 

pictureBox1.BackColor = Color.Transparent; 
pictureBox1.Image = bmp; 

आप कलम निपटाने और ब्रश करना है? बीएमपी और जी के बारे में क्या?

मेरा मुख्य प्रश्न यह है कि, यदि इन्हें मैन्युअल रूप से निपटाना था, तो वे दायरे से बाहर निकलने के तुरंत बाद क्यों नहीं निकलते? क्या यह होगा, अगर आपने उन्हें मैन्युअल रूप से निपटान नहीं किया है? क्या यह देरी है जो लोगों को मैन्युअल रूप से ऐसा करती है?

उत्तर

1

हाँ, बीएमपी, जी, बी और पी सभी पहचान योग्य हैं, आपको उन सभी को निपटाना चाहिए()। पसंदीदा रूप से using() {} ब्लॉक का उपयोग करके।

अपवाद हैं, जब आप Pen p2 = Pens.Blue; का उपयोग करते हैं तो आपको पी 2 का निपटान नहीं करना चाहिए। इसे स्टॉक आइटम कहा जाता है। Brushes.Black आदि के लिए भी

के लिए क्यों, यह सभी डिस्पोजेबल कक्षाओं के लिए समान है। .Net संदर्भ गणना का उपयोग नहीं करता है, इसलिए जब कोई संदर्भ दायरे से बाहर हो जाता है तो तत्काल कार्रवाई नहीं होती है (नहीं हो सकती)।

और इसे कचरा कलेक्टर को छोड़कर अंततः उन्हें मुक्त कर दिया जाएगा लेकिन यह (बहुत) अक्षम है। मुझे एक एएसपी.नेट (!) एप्लिकेशन पता है जो ग्राफिक हैंडल की कमी पर असफल रहा क्योंकि तुरंत उन्हें निपटाने की आवश्यकता नहीं है। यह छवियां उत्पन्न कर रहा था।

+0

धन्यवाद हेनक। यदि आप पेन पर निपटान कहते हैं तो क्या होता है। ब्लू? क्या यह खराब है? –

+1

आप जानते हैं, मुझे वास्तव में पता नहीं है। मैं कोशिश करने से पहले अनुमान लगाऊंगा: या तो आप तुरंत अपवाद प्राप्त करते हैं या कुछ भी नहीं होता है। –

+1

मैंने कोशिश की: आप संदेश है कि परिवर्तन की अनुमति नहीं है के साथ एक System.ArgumentException मिलता है। –

1

निपटान का उपयोग अप्रबंधित संसाधनों का निपटान करने के लिए किया जाता है।

तो, अंगूठे के नियम के रूप में, मैं एक उपयोग कथन में IDISposable ऑब्जेक्ट्स के किसी भी तत्कालता को लपेटता हूं, इसलिए मुझे चिंता करने की ज़रूरत नहीं है कि एक पेन के अप्रबंधित संसाधन के बारे में चिंता करने की ज़रूरत नहीं है।

17

हां, आपको केवल उन्हें पेन और ब्रश नहीं बल्कि Bitmap और Graphics का निपटान करना होगा।

जब वे दायरे से बाहर होते हैं तो वे डिस्पोजेक्ट नहीं करते हैं क्योंकि वेरिएबल्स स्वयं संदर्भ हैं, ऑब्जेक्ट्स नहीं हैं, और सी # कंपाइलर यह नहीं जानता कि स्वामित्व अभी भी उन संदर्भों से संबंधित है या नहीं (उदाहरण के लिए FillEllipse सिद्धांत, इसे दिए गए संदर्भ को याद रखें, और कुछ पल में इसका उपयोग करने का प्रयास करें - याद रखें कि भाषा संकलक के पास लाइब्रेरी अर्थशास्त्र का कोई विशेष ज्ञान नहीं है!)।

आप संकेत मिलता है कि स्वामित्व है कि गुंजाइश के लिए प्रतिबंधित है चाहते हैं, आप using बयान का उपयोग करें:

using (Bitmap bmp = new Bitmap (100, 100)) 
using (Graphics g = Graphics.FromImage (bmp)) 
using (Pen p = new Pen (Color.FromArgb (128, Color.Blue), 1)) 
using (Brush b = new SolidBrush (Color.FromArgb (128, Color.Blue))) 
{ 
    g.FillEllipse (b, 0, 0, 99, 99);  
    g.FillRegion (b, pictureBox1.Region); 
} 

इस संकलक डालने सुनिश्चित करना है कि सभी वस्तुओं को एक बार पसंद हैं स्वचालित रूप से रूप में की जरूरत Dispose करने के लिए कॉल कर देगा संबंधित using गुंजाइश छोड़ी गई है (चाहे सामान्य रूप से, नियंत्रण स्थानांतरण द्वारा return या break, या अपवाद)।

आप एक सी से आते हैं ++ पृष्ठभूमि, using सी # में सीधे एक const std::auto_ptr के अनुरूप है, सिवाय इसके कि यह एक भाषा निर्माण के यहाँ है कि, और केवल (अर्थात वर्ग क्षेत्रों के लिए नहीं) स्थानीय चर के लिए इस्तेमाल किया जा सकता है।

+1

वास्तव में? दिलचस्प। मैं कभी नहीं देखा है कि कुछ भी लेकिन ग्राफिक्स से पहले आपत्ति है। क्या कोई एमएस साइट है जो इसके बारे में अधिक जानकारी में बात करती है? – derGral

+4

यह सच है कि आपको 'निपटान' को कॉल करना चाहिए या 'उपयोग' कथन को नियोजित करना चाहिए, लेकिन यह सच नहीं है कि 'पेन' अन्यथा दायरे से बाहर नहीं निकाला जाएगा क्योंकि कुछ एपीआई इसका उपयोग कर रहे हैं। 'पेन' में एक फाइनेंजर होता है, जो पहुंचने योग्य होने के बाद कुछ अनिर्दिष्ट समय पर चलाया जाएगा (एक अल्पकालिक वस्तु के लिए यह बहुत जल्द हो सकता है), और जब ऐसा होता है, तो यह 'निपटान' के बराबर होता है। –

+1

देखें: http://msdn.microsoft.com/en-us/library/system.drawing.pen.dispose.aspx - "कॉल का निपटान करें ... अन्यथा, जो संसाधन इसका उपयोग कर रहे हैं उन्हें कचरा कलेक्टर तक मुक्त नहीं किया जाएगा पेन ऑब्जेक्ट की अंतिम विधि को कॉल करता है। " –

3

सी # चीजों से बाहर निकलने के बाद चीजों को "नष्ट" या निपटान नहीं करता है।

उन वर्गों सबसे अधिक संभावना स्वचालित रूप से अप्रबंधित संसाधनों है कि वे अपने विशेष Finalizer विधि है, जो जब वे क्षेत्र से बाहर जाने के बाद एक अनिश्चित समय में कचरा एकत्र कर रहे हैं बुलाया जाएगा में पर पकड़ रिक्त हो जाएगा।

लेकिन उस पर भरोसा करना आपके नियंत्रण से बाहर कुछ पर भरोसा करना है, और शायद कुछ समय के लिए नहीं हो सकता है। वर्ग IDisposable लागू करता

हैं, तो सबसे अच्छा अभ्यास आप मैन्युअल रूप से Dispose() कहीं कॉल करने के लिए, या अधिमानतः एक using ब्लॉक में लपेट है। इस तरह आप यह सुनिश्चित कर सकते हैं कि:

ए अप्रबंधित संसाधन निश्चित रूप से मुक्त हो रहे हैं।

बी। अप्रबंधित संसाधनों को जितनी जल्दी हो सके मुक्त कर दिया गया है।

6

मैं अन्य लोगों के कोड उदाहरण यहाँ डाल दिया है पता है, लेकिन मैं इतना शुरू कर दिया मैं खत्म करेंगे:

using (Bitmap bmp = new Bitmap(100, 100)) 
{ 
    using (Graphics g = Graphics.FromImage(bmp)) 
    { 
    using (Pen p = new Pen(Color.FromArgb(128, Color.Blue), 1)) 
    { 
     using (Brush b = new SolidBrush(Color.FromArgb(128, Color.Blue))) 
     { 
     g.FillEllipse(b, 0, 0, 99, 99); 
     g.FillRegion(b, pictureBox1.Region); 

     pictureBox1.BackColor = Color.Transparent; 
     pictureBox1.Image = bmp; 
     } 
    } 
    } 
} 

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

+3

सही है, लेकिन यह कई उपयोगों को 1 ब्रेस जोड़ी में पैवेल के नमूने की तरह फोल्ड करने के लिए प्रथागत (बनना) है। –

+1

कूल, मैंने पहले उस तकनीक को नहीं देखा है। सोचो कि मैं इसे अब से शुरू कर दूंगा (अब कोई इरादा नहीं है) :) –

+0

यस्टर मैंने एक [प्रश्न] (http://stackoverflow.com/q/14946381/799558) का जवाब दिया, इसे बिटमैप को निपटाने के बाद इसे ' pictureBox1.Image' और मेरा जवाब बिल्कुल तुम्हारी तरह था (मैंने पहले ही अपना जवाब हटा दिया है)। उन्होंने मुझे बताया कि चित्र छवि भी निपटान की जाएगी। क्या मैं अभी भी इस स्थिति में 'उपयोग' का उपयोग कर सकता हूं? – AbZy

2

डिस्पोजेबल पैटर्न सही ढंग से इस्तेमाल किया जाता है, Disposeहै नहीं अत्यंत आवश्यक होता - यह, जब वस्तु को अंतिम रूप दिया गया है बुलाया जाएगा तो तुम संसाधनों या कुछ भी लीक नहीं होगा।

हालांकि, यह, जैसे ही आप वस्तु उपयोग समाप्त होते Dispose कॉल करने के लिए disposables अक्सर सीधे देशी संसाधनों जो आम तौर पर सीमित हैं पर नियंत्रण के रूप में अच्छे संस्कार है। ऑब्जेक्ट्स को आम तौर पर अंतिम रूप से अंतिम रूप से एकत्रित/एकत्र नहीं किया जाता है, इसलिए जब आप ऑब्जेक्ट का उपयोग नहीं कर लेते हैं, तो वे संसाधन बस लटकते हैं, बर्बाद हो जाते हैं। मुक्त कर देते निपटान उन संसाधनों तुरंत, तो वे कार्यक्रम (या कुछ मामलों में, अन्य कार्यक्रमों के द्वारा) के अन्य भागों के द्वारा प्रयोग किया जा सकता है।

ध्यान दें, एक using ब्लॉक स्वचालित रूप से जब आप इसे पूरा कर चुके हैं, जिसके कारण आप शायद ही कभी अगर कभी Dispose एक using ब्लॉक के भीतर देख वस्तु disposes।

लघु संस्करण: वस्तु IDisposable लागू करता है, और अपने कोड में यह बनाया है (यानी: अगर यह Pens.Blue की तरह एक प्रणाली वस्तु, या Graphics आप OnPaint आदि में पारित नहीं है), यह निपटारा किया जाना चाहिए जब आप पूरी तरह से कर रहे हैं इसके साथ किया - Dispose को फोन करके या नहीं, या किसी अन्य विधि (Close एक आम एक है), या एक using ब्लॉक का उपयोग करके कि Dispose कॉल करने के लिए निर्दिष्ट फोन करके। आप पर का निपटान नहीं करते हैं, लेकिन आपको लगभग हमेशा चाहिए।

+1

छोड़े जाने पर बहुत सारी वस्तुएं स्वयं को साफ़ नहीं कर पाएंगी। जबकि कुछ मामलों में क्लीनअप काफी सरल है, दूसरों में यह अनिवार्य रूप से असंभव है। जब तक कोई यह नहीं जानता कि किसी विशेष वर्ग की वस्तुओं को त्यागना सुरक्षित है, तो किसी को यह मानना ​​चाहिए कि कॉल किए बिना वस्तुओं को त्यागना सबसे पहले बुरी चीजें होने का कारण बनेंगे। – supercat

+0

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

+0

मान लीजिए कि कोई एक क्लास चेंज काउंटर बनाना चाहता है जिसका कन्स्ट्रक्टर एक इंटोटिफाप्रॉपर्टी चेंज ऑब्जेक्ट स्वीकार करता है, और यह रिपोर्ट करेगा कि उस ऑब्जेक्ट ने कितनी बार अपनी संपत्ति को बढ़ाया है क्योंकि यह (चेंज काउंटर) बनाया गया था। त्याग दिए जाने पर इस तरह के एक वर्ग को अपने आप के बाद साफ कर सकते हैं? ध्यान रखें कि INotifyPropertyChanged वादा करता है कि PropertyChanged.RemoveHandler के कार्यान्वयन को फाइनलाइज़र थ्रेड से सुरक्षित रूप से उपयोग किया जा सकता है। – supercat

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