2010-07-31 11 views
8

सी # में फ़ाइलों के साथ काम करते समय, मुझे संबंधित संसाधनों को मुक्त करने के बारे में सोचने की शर्त है। आम तौर पर यह एक प्रयोग कथन है, जब तक कि यह एक लाइनर सुविधा विधि फ़ाइल.ReadAllLines की तरह नहीं है, जो मेरे लिए फ़ाइल खोल और बंद कर देगा।फ़ाइल करता है। रीडलाइन मुक्त संसाधन

.NET 4.0 ने सुविधा विधि फ़ाइल.रेडलाइन पेश की है। यह एक IENumerable देता है और फ़ाइल को संसाधित करने के लिए एक अधिक कुशल तरीका के रूप में बिल किया जाता है - यह पूरी फ़ाइल को स्मृति में संग्रहीत करने से बचाता है। ऐसा करने के लिए मुझे लगता है कि गणक में कुछ स्थगित निष्पादन तर्क है।

जाहिर है क्योंकि यह विधि एक आईनेमरेबल, नहीं और आईडीस्पोजेबल लौटाती है, इसलिए मैं एक उपयोग कथन की मेरी आंत प्रतिक्रिया के साथ नहीं जा सकता।

मेरे प्रश्न हैं: इस बात के साथ, क्या इस विधि के साथ संसाधन विलोपन पर कोई गठजोड़ है?

क्या इस विधि को कॉल करना मतलब है कि संबंधित फ़ाइल ताले की रिहाई गैर-निर्धारक है?

उत्तर

12

IEnumerable IDisposable से विरासत नहीं है, क्योंकि आम तौर पर, वर्ग है कि यह लागू करता है सिर्फ तुम गणनीय होने का वादा देता है, यह वास्तव में कुछ भी नहीं अभी तक किया है कि वारंट निपटान।

हालांकि, जब आप इसे ऊपर की गणना, आपको पहले एक IEnumeratorIEnumerable.GetEnumerator विधि को फोन करके पुनः प्राप्त, और आम तौर पर, अंतर्निहित वस्तु तुम वापस मिल को लागू करता है IDisposable

रास्ता foreach कार्यान्वित किया जाता है इस के समान है:

var enumerator = enumerable.GetEnumerator(); 
try 
{ 
    // enumerate 
} 
finally 
{ 
    IDisposable disposable = enumerator as IDisposable; 
    if (disposable != null) 
     disposable.Dispose(); 
} 

इस तरह, यदि वस्तु वास्तव में IDisposable को लागू करता है, यह का निपटारा कर दिया जाएगा। File.ReadLines के लिए, फ़ाइल वास्तव में तब तक नहीं खोली जाती जब तक कि आप इसे गिनती शुरू नहीं करते हैं, इसलिए File.ReadLines से प्राप्त ऑब्जेक्ट को निपटान की आवश्यकता नहीं है, लेकिन आपके द्वारा प्राप्त गणक को करता है।

के रूप में टिप्पणी से संकेत मिलता है, IEnumeratorIDisposable से विरासत नहीं है, भले ही कई विशिष्ट कार्यान्वयन करता है, जबकि सामान्य IEnumerator<T>IDisposable वारिस है।

+0

दरअसल, आईनेमेरेटर IDISposable लागू नहीं करता है। लेकिन आईन्यूमेरेटर के कई * कार्यान्वयन * IDISposable, और foreach loop, और LINQ एक्सटेंशन विधियों को लागू करते हैं, सभी यह देखने के लिए 'as' cast करते हैं कि गणनाकर्ता IDISposable लागू करता है, और यदि ऐसा है तो वे निपटान कहते हैं। –

+2

सुधार: गैर-जेनेरिक आईन्यूमेरेटर IDISposable लागू नहीं करता है, लेकिन जेनेरिक एक ('IENumerator ') करता है। –

+0

आह, आप सही हैं। गह, मूर्खतापूर्ण गलती, मुझे जवाब संपादित करने दें। –

2

लास के उत्तर के लिए +1।

File.ReadLines के लिए विशेष रूप से

जहां प्रगणक .MoveNext() आंतरिक TextReader जब यह एक EOF का सामना करना पड़ता है, या यदि एक दोष होता है का निपटारा किया जाएगा कहते हैं।

private bool MoveNext() 
{ 
    bool flag; 
    try 
    { 
     switch (this.<>1__state) 
     { 
      case 0: 
       this.<>1__state = -1; 
       this.<>7__wrap2 = this.reader; 
       this.<>1__state = 1; 
       this.<line>5__1 = null; 
       goto Label_005C; 

      case 2: 
       this.<>1__state = 1; 
       goto Label_005C; 

      default: 
       goto Label_0078; 
     } 
    Label_003E: 
     this.<>2__current = this.<line>5__1; 
     this.<>1__state = 2; 
     return true; 
    Label_005C: 
     if ((this.<line>5__1 = this.reader.ReadLine()) != null) 
     { 
      goto Label_003E; 
     } 
     this.<>m__Finally3(); // Disposal at end of file. 
    Label_0078: 
     flag = false; 
    } 
    fault 
    { 
     this.System.IDisposable.Dispose(); // Disposal due to fault. 
    } 
    return flag; 
} 
संबंधित मुद्दे