2013-01-07 11 views
20

मेरे पास स्थगित निष्पादन और डेटा का निपटान करने के बारे में एक प्रश्न है।"उपयोग" कथन के भीतर उपज का उपयोग करते समय, कब निपटान होता है?

private IEnumerable<string> ParseFile(string fileName) 
{ 
    using(StreamReader sr = new StreamReader(fileName)) 
    { 
     string line; 
     while((line = sr.ReadLine()) != null) 
     { 
      yield return line; 
     } 
    } 
} 

private void LineReader(string fileName) 
{ 
    int counter = 0; 

    foreach(string line in ParseFile(fileName)) 
    { 
     if(counter == 2) 
     { 
      break; // will this cause a dispose on the StreamReader? 
     } else 
     { 
      Console.WriteLine(line); 
      counter++; 
     } 
    } 
} 

break बयान तुरंत ParseFile में पाठक निपटान के लिए कारण या यह अभी भी संदर्भ में माना जाता है और जब तक कार्यक्रम में ही बंद कर दिया है फ़ाइल खुला लॉक हो जाएगा होगा:

निम्नलिखित उदाहरण पर विचार?

+2

एक त्वरित कंसोल ऐप लिखें और पता लगाएं :) – jjxtra

+0

काउंटर दो हिट करते समय 'ब्रेक' का उपयोग करने के बजाय ओह साइड नोट, बस 'पारसेफाइल' के अंत में 'टेक (2) 'जोड़ें। – Servy

+1

जॉन स्कीट की पुस्तक "सी # गहराई में" उठाएं यदि आप इटरेटर ब्लॉक में क्या होता है, या केवल भाषा की कल्पना को देखते हुए वास्तव में अच्छी व्याख्या करना चाहते हैं, जैसा कि वह अक्सर सुझाता है। –

उत्तर

16

तो हमारे यहां कई अलग-अलग मुद्दे चल रहे हैं।

पहले बंद, इटरेटर ब्लॉक में using से निपटने। IEnumeratorIDisposable बढ़ाता है। कोडर इटेटरेटर ब्लॉक उत्पन्न करने वाला कोड वास्तव में इतना मजबूत है कि किसी भी कोशिश/आखिरकार ब्लॉक (using परिणाम try/finally ब्लॉक बनने के परिणामस्वरूप) finally की सामग्री में परिणामस्वरूप Dispose अंकुश के तरीके में कॉल किया जा रहा है, अगर यह नहीं था पहले से ही बुलाया इसलिए जब तक गणनाकर्ता का निपटारा किया जाता है, यह StreamReader को रिसाव नहीं करेगा।

तो अब हम खुद से पूछते हैं कि गणनाकर्ता का निपटारा किया गया है या नहीं। सभी foreach बयान अंक पर Dispose पर कॉल करेंगे (इसे IDisposable लागू करना चाहिए)। वे break या return कथन का उपयोग करते हुए बाहर निकलने पर भी ऐसा करते हैं, साथ ही जब यह सामान्य रूप से समाप्त होता है।

तो तुम ऐसे मामलों में जहां कुछ भी नहीं (अर्थात किसी मशीन unpugging) लीक से रोका जा सकता है को छोड़कर यह सुनिश्चित करें कि सभी परिस्थितियों में संसाधन लीक नहीं किया जाएगा हो सकता है।

+0

यह उससे थोड़ा अधिक जटिल है। ओपी के मामले में, इटेटर पूरी तरह से ब्रेक स्टेटमेंट के कारण निपटान करेगा। लेकिन ParseFile के लिए कॉल 'स्थानीय-उपयोग' के अंदर StreamReader का संदर्भ प्रस्तुत करता है जो अब दायरे से बाहर हो गया है। मुझे लगता है कि यह कतार में अंतिम कतार पर कतार है और एकत्रित होने पर निपटाया जाता है? – n8wrl

+3

@ n8wrl नहीं, यह सच नहीं है। जब 'आईएन्यूमेरेटर' को 'foreach' लूप द्वारा निपटाया जाता है तो यह' StreamReader' पर निपटान करेगा (माना जाता है कि यह उस बिंदु पर 'उपयोग के' के अंदर था)। इस तरह इटेटरेटर ब्लॉक लागू किए गए थे; ऐसा करने के लिए। – Servy

+0

मुझे लगता है कि हमें साइकोडाड की सलाह लेनी चाहिए और इसे आजमाएं क्योंकि यह बहुत अच्छा होगा अगर यह काम करता है! – n8wrl

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