我有一个关于延迟执行和数据处理的问题。
考虑以下示例:
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
中的读取器进行处理,或者它是否仍在上下文中考虑并会锁定文件打开直到程序本身关闭?
最佳答案
所以我们这里有几个不同的问题。
首先,处理迭代器 block 中的using
。 IEnumerator
扩展 IDisposable
。生成迭代器 block 的代码实际上足够健壮,任何 try/finally block (using
导致 try/finally
block 被创建)导致 finally
阻止在枚举器的 Dispose
方法中调用(如果尚未调用)。所以只要释放枚举器,它就不会泄漏StreamReader
。
所以现在我们问自己枚举器是否被释放。所有 foreach
语句都将在枚举器上调用 Dispose
(它应该实现 IDisposable
)。即使您使用 break
或 return
语句退出,它们也会这样做,以及当它正常完成时。
因此您可以确定在任何情况下资源都不会泄漏,除非没有可以防止泄漏的情况(即有人拔掉机器)。
关于c# - 在 "using"语句中使用 yield 时,Dispose 何时发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203941/