在“using”语句中使用yield时,Dispose何时发生?

我有一个关于延迟执行和处理数据的问题。

请考虑以下示例:

private IEnumerable 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的读者处置还是仍然在上下文中考虑并将文件锁定直到程序本身关闭?

所以我们在这里有几个独立的问题。

首先,处理迭代器块中的usingIEnumerator扩展了IDisposable 。 生成迭代器块的代码实际上足够强大,任何try / finally块( using导致创建try/finally块的结果)都会导致在枚举器的Dispose方法中调用finally块的内容,如果它不是已经打过电话了。 因此,只要放置了枚举器,它就不会泄漏StreamReader

所以现在我们问自己是否处置了调查员。 所有foreach语句都将在枚举器上调用Dispose (它应该实现IDisposable )。 即使您使用breakreturn语句退出,以及正常结束时,它们也会这样做。

因此,您可以确保在任何情况下都不会泄露资源,除非可以防止任何事情泄漏(即有人擅自拆除机器)。