22

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

考虑以下示例:

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进行处理,或者它是否仍然在上下文中考虑并将锁定文件打开直到程序本身关闭?

4

1 回答 1

18

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

首先,处理using迭代器块中的 。 IEnumerator延伸IDisposable。生成迭代器块的代码实际上足够健壮,以至于任何 try/finally 块(using导致try/finally创建块)都会导致finally块的内容在枚举器的方法中被调用Dispose,如果它还没有被调用的话。所以只要枚举器被释放,它就不会泄漏StreamReader.

所以现在我们问自己,枚举数是否被释放。所有foreach语句都将调用Dispose枚举器(如果它实现IDisposable)。即使您使用breakorreturn语句退出以及正常完成时,它们也会这样做。

因此,您可以确保在任何情况下资源都不会泄露,除非出现无法防止泄露的情况即有人拔掉机器)。

于 2013-01-07T21:07:10.233 回答