2009-10-02 18 views
7

C'è un modo in un blocco iteratore C# per fornire un blocco di codice che verrà eseguito quando termina il foreach (o naturalmente per essere interrotto), ad esempio per ripulire le risorse?'Finally' Block in Iterators

Il meglio che ho imparato è usare il costrutto using, che va bene ma ha bisogno di una classe IDisposable per fare il clean up. Ad esempio:

public static IEnumerable<string> ReadLines(this Stream stream) 
    { 
     using (StreamReader rdr = new StreamReader(stream)) 
     { 
      string txt = rdr.ReadLine(); 
      while (txt != null) 
      { 
       yield return txt; 
       txt = rdr.ReadLine(); 
      } 
      rdr.Close(); 
     } 
    } 

risposta

5

try/finally funziona bene, fintanto che il chiamante sia utilizzando un foreach o manualmente invita Dispose sul IEnumerator<T>. Per essere onesti, se si tratta di ripulire le risorse, una dichiarazione using probabilmente sarà il modo migliore di farlo in ogni caso - se si sta utilizzando una risorsa che ha bisogno di essere pulita ma non implementa IDisposable, è una preoccupazione in sé :)

Ci sono alcune restrizioni su cosa è possibile fare nei blocchi iteratore, come explained on Eric Lippert's blog, ma nella maggior parte dei casi tutto funziona molto bene.

È possibile trovare my article about iterator block implementation interessante in termini di come viene tradotto finally.

0

try/finally funziona in questo caso.

public static IEnumerable<string> ReadLines(this Stream stream) 
{ 
    StreamReader rdr = new StreamReader(stream); 

    try 
    { 
     string txt = rdr.ReadLine(); 
     while (txt != null) 
     { 
      yield return txt; 
      txt = rdr.ReadLine(); 
     } 
     rdr.Close(); 
    } 
    finally 
    { 
     rdr.Dispose(); 
    } 
}