I have a question regarding deferred execution and the disposing of data.
Consider the following example:
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++; } } }
Will the break
statement immediately cause the reader in ParseFile
to dispose or is it still considered in context and will lock the file open until the program itself is closed?
So we have several separate issues going on here.
First off, dealing with the using
in the iterator block. IEnumerator
extends IDisposable
. The code that generates iterator blocks is actually robust enough that any try/finally blocks (a using
results in a try/finally
block being created) results in the contents of the finally
block being called in the Dispose
method of the enumerator, if it wasn't already called. So as long as the enumerator is disposed, it won't leak the StreamReader
.
So now we ask ourselves if the enumerator is disposed. All foreach
statements will call Dispose
on the enumerator (should it implement IDisposable
). They do so even if you exit using a break
or return
statement, as well as when it finishes normally.
So you can be sure that under all circumstances the resource won't be leaked, barring the cases where nothing can be prevented from leaking (i.e. someone unpugging the machine).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With