c# - 在 "using"语句中使用 yield 时,Dispose 何时发生?

标签 c# file-io using deferred-execution

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

考虑以下示例:

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 中的usingIEnumerator 扩展 IDisposable。生成迭代器 block 的代码实际上足够健壮,任何 try/finally block (using 导致 try/finally block 被创建)导致 finally 阻止在枚举器的 Dispose 方法中调用(如果尚未调用)。所以只要释放枚举器,它就不会泄漏StreamReader

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

因此您可以确定在任何情况下资源都不会泄漏,除非没有可以防止泄漏的情况(即有人拔掉机器)。

关于c# - 在 "using"语句中使用 yield 时,Dispose 何时发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203941/

相关文章:

c# - 在 C# 中嵌套 'using' 相当于 typedef

c# - Backgroundworker RunWorkerCompleted 事件甚至在完成工作之前就已触发

c# - 从c#中的字符串中提取最后一个匹配项

c# - 如何分割 '-'前后的字符串

c - 如何在不更改内容的情况下更新文本文件

c++ - 代码中没有任何 STL 的 STL 错误

c# - 使用 block 与功能 block

c# - 如何在软键盘Unity3d中检测 "done"按钮

c - 使用 C 从文件中删除所有重复行

python - IOError: [Errno 22] 无效模式 ('wb' ) 或文件名: