2010-01-27 12 views
6

उदाहरण के लिए, नीचे दिए गए कोड में एक 'image'object और बनाया जाएगा तो कचरा भविष्य में किसी अज्ञात बिंदु पर एकत्रक्या सी # लिखना संभव है ताकि ऑब्जेक्ट्स कचरे से बाहर निकलने पर कचरा इकट्ठा हो?

void MyFunction() { 

    Bitmap image = RetrieveImage(); 
    DoSomething(image); 
} 

क्या

के बारे में
void MyFunction() { 

    DoSomething(RetrieveImage()); 

} 

इस मामले में वस्तु है एक बार यह गुंजाइश से बाहर हो जाता है यानी MyFunction के अंत के बाद कचरा इकट्ठा किया जाता है। यदि ऐसा नहीं है तो इसे लागू करने के लिए कहीं नहीं है?

+3

मैं 1 und 2. के बीच कोई अंतर नहीं दिख रहा है यह क्यों व्यवहार करना चाहिए विभिन्न कचरा संग्रहण के लिहाज से (इस ऑब्जेक्ट दायरे से बाहर गिर IDisposable को लागू कि कोई भी यह सोचते हैं जाता है)? – flq

+2

मैं वास्तव में "आप यह क्या चाहते हैं" प्रकार की टिप्पणियों का वकील नहीं हूं, लेकिन गंभीरता से, .NET कचरा कलेक्टर वास्तव में प्रोग्रामर से बेहतर जानता है जब यह कुछ सफाई करने का एक अच्छा समय है। ध्यान रखें कि .NET VM एक वास्तविक समय प्रणाली नहीं है। अगर आपके पास अप्रबंधित संसाधन हैं, तो IDISposable और उपयोग का उपयोग करें। –

+0

आपको मानक कचरा कलेक्टर पर भरोसा करना चाहिए - यदि आप कचरा संग्रहण को मजबूर करना चाहते हैं तो आप प्रदर्शन खो देंगे। क्या ऐसा कोई विशेष कारण है जब आप ऐसा करते हैं जब आप ऐसा करते हैं? – jball

उत्तर

19

नहीं। असल में, आप वास्तव में इसे कचरा इकट्ठा नहीं करना चाहते हैं - कचरा कलेक्टर को संकेत देना अक्सर प्रदर्शन को कम करेगा।

आप चाहते क्या कर एक समय पर ढंग अप्रबंधित संसाधनों के निपटान के लिए है - और कि जहां IDisposable भूमिका शुरू होती है, using बयान के साथ:

void MyFunction() 
{ 
    using (Bitmap image = RetrieveImage()) 
    { 
     DoSomething(image); 
    } 
} 

कि image.Dispose() फोन करेगा यह पत्ते के रूप में using कथन, चाहे DoSomething एक अपवाद फेंक दिया हो।

आप हालांकि अतिरिक्त चर का उपयोग करना है - जब तक आप DoSomething बदलने के बजाय एक Func<Bitmap> लेने के लिए है, तो बजाय:

void DoSomething(Bitmap image) 
{ 
    // Code here 
} 
... 
DoSomething(RetrieveImage()); 

आप होगा:

void DoSomething(Func<Bitmap> imageProvider) 
{ 
    using (Bitmap image = imageProvider()) 
    { 
     // Code here 
    } 
} 
... 
DoSomething(() => RetrieveImage()); 

ध्यान दें कि कि बिना के बिना बिटमैप में पास करने का अवसर नहीं देता है - यदि आप इसे बाद में उपयोग करना चाहते हैं तो समस्या हो सकती है। फिर भी, कम से कम इसके बारे में जानने के लिए यह एक अच्छी तकनीक है।

संपादित करें: जैसा कि मबेकिश ने अपनी टिप्पणियों में बताया है, RetrieveImage के भीतर बिटमैप का निपटान करने पर यहां बहुत अधिक लाभ नहीं है। यहाँ हालांकि तर्ज पर एक प्रकार है:

public void ApplyToEachLineInFile(string file, Action<string> action) 
{ 
    using (TextReader reader = File.OpenText(file)) 
    { 
     string line; 
     while ((line = reader.ReadLine()) != null) 
     { 
      action(line); 
     } 
    } 
} 

यहाँ "अधिग्रहण और निपटान के" तर्क समझाया गया है, फोन करने वाले को इसके बारे में चिंता किए बिना - लेकिन फोन करने वाले अभी भी तर्क की जटिलता वे पारित करने के मामले में बहुत लचीला हो सकता है में

+0

प्रदाता प्रतिनिधि में गुजरने का अच्छा सुझाव। यह कई मामलों में एक बहुत ही उपयोगी पैटर्न है। –

+0

यह DoSomething से बेहतर क्यों है (पुनर्प्राप्ति इमेज()); और DoSomething में बिटमैप का निपटान? – mbeckish

+0

क्योंकि अगर बिटमैप को DoSomething में पास किया जाता है, तो कुछ कैसे पता चलता है कि यह निपटान सुरक्षित है या नहीं? क्या होगा यदि कॉलर DoSomethingElse को बिटमैप को पास करने के बाद इसे पास करना चाहता था? –

4

कचरा संग्रह तब नहीं होता जब कोई ऑब्जेक्ट गुंजाइश से बाहर हो जाता है। इसके बजाय यह ढांचे से एक स्वचालित स्मृति प्रबंधन समारोह है।

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

आप कचरा एकत्र करने के लिए नेट मजबूर कर सकते हैं, लेकिन जब तक आप गंभीर स्मृति समस्याओं का सामना कर रहे हैं, मैं सलाह नहीं आप उस पथ नीचे जाना।

+0

सहमत है, कचरा कलेक्टर मैन्युअल रूप से इसे आविष्कार करने के विरोध में स्वचालित रूप से कचरा कलेक्टर अपने कार्यों को स्वचालित रूप से करने देता है। –

0

आप के साथ कूड़ा संग्रह को लागू कर सकते हैं: यह ठीक से निपटान के बाद

System.GC.Collect()

(के लिए Jons जवाब को देखने का उपयोग कर() {} - सिंटेक्स)।

< संपादित करें>

(जैसा कि मैंने अभी किया) मत भूलना

System.GC.WaitForPendingFinalizers();

बाद में।

</संपादित करें>

हालांकि यह अनुशंसित नहीं है - के रूप में जॉन ने कहा।

+1

कॉलिंग कलेक्ट * गारंटी * नहीं करता है कि एक वस्तु जो दायरे से बाहर है वास्तव में एकत्र हो जाती है। कई रोचक और विचित्र परिदृश्य हैं जिनमें ऐसी वस्तु थोड़ी देर तक रह सकती है। यह भी ध्यान रखें कि यदि आप संग्रह को मजबूर कर रहे हैं तो आपको आम तौर पर लंबित अंतिमकर्ताओं के लिए प्रतीक्षा करनी चाहिए; लंबित फाइनलर एक और थ्रेड पर चलते हैं, इसलिए दौड़ हो सकती है। –

+0

सच है। धन्यवाद।हमारे द्वारा उपयोग किए गए कोड की प्रतिलिपि बनाई जानी चाहिए;) – Leonidas

3

नोट: आप यह नहीं करना चाहते हैं। .NET कचरा कलेक्टर आपके से "स्मार्ट" है (या मुझे, या जॉन स्कीट या कोई और)।

try 
{ 
    Bitmap image = RetrieveImage(); 
    DoSomething(image); 
} 
finally 
{ 
    GC.Collect(); 
} 

+1

ध्यान दें कि इसके लिए काम करना महत्वपूर्ण है कि 'image' चर को 'try' कथन के अंदर घोषित किया जाना चाहिए। अन्यथा, रनटाइम ऑब्जेक्ट को पहुंचने योग्य नहीं मान सकता है या नहीं, और आप इसे उच्च पीढ़ी तक प्रचारित कर सकते हैं, जिससे ऑब्जेक्ट को कचरे से एकत्रित होने से प्रभावी ढंग से रोक दिया जा सकता है। –

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