File.ReadLines 啥时候释放资源
Posted
技术标签:
【中文标题】File.ReadLines 啥时候释放资源【英文标题】:When does File.ReadLines free resourcesFile.ReadLines 什么时候释放资源 【发布时间】:2011-03-23 16:44:30 【问题描述】:在使用 C# 处理文件时,我习惯于考虑释放相关资源。通常这是一个 using 语句,除非它是一个单一的便捷方法 比如 File.ReadAllLines,它将为我打开和关闭文件。
.Net 4.0 引入了便捷方法 File.ReadLines。这将返回一个 IEnumerable,并被认为是一种更有效的文件处理方式——它避免了将整个文件存储在内存中。为此,我假设枚举器中有一些延迟执行逻辑。
显然,由于此方法返回的是 IEnumerable,而不是 IDisposable,因此我无法接受 using 语句的直觉反应。
我的问题是: 考虑到这一点,使用这种方法释放资源是否有任何陷阱?
调用这个方法是否意味着关联文件锁的释放是不确定的?
【问题讨论】:
【参考方案1】:IEnumerable
不从 IDisposable 继承,因为通常,实现它的类只为您提供可枚举的承诺,它实际上还没有做任何需要处置的事情。
但是,当您枚举它时,您首先通过调用IEnumerable.GetEnumerator
方法检索IEnumerator
,通常,您返回的底层对象确实实现IDisposable
。
foreach
的实现方式类似这样:
var enumerator = enumerable.GetEnumerator();
try
// enumerate
finally
IDisposable disposable = enumerator as IDisposable;
if (disposable != null)
disposable.Dispose();
这样,如果对象确实实现了IDisposable
,它将被丢弃。对于File.ReadLines
,文件在您开始枚举之前不会真正打开,因此您从File.ReadLines
获得的对象不需要处理,但您获得的枚举器需要处理。
正如 cmets 所指出的,IEnumerator
不继承自 IDisposable
,尽管许多典型实现确实如此,而通用 IEnumerator<T>
确实继承 IDisposable
。
【讨论】:
实际上,IEnumerator 并没有实现 IDisposable。但是 IEnumerator 的许多实现确实实现了 IDisposable,foreach 循环和 LINQ 扩展方法都执行as
强制转换以查看枚举器是否实现了 IDisposable,如果是,它们调用 Dispose。
更正:非泛型 IEnumerator 不实现 IDisposable,但泛型 (IEnumerator<T>
) 可以。
啊,你是对的。啊,愚蠢的错误,让我编辑答案。【参考方案2】:
+1 表示 Lasse 的回答。
特别是对于枚举器调用.MoveNext()
的File.ReadLines
,内部TextReader
将在遇到EOF 或发生故障时被释放。
private bool MoveNext()
bool flag;
try
switch (this.<>1__state)
case 0:
this.<>1__state = -1;
this.<>7__wrap2 = this.reader;
this.<>1__state = 1;
this.<line>5__1 = null;
goto Label_005C;
case 2:
this.<>1__state = 1;
goto Label_005C;
default:
goto Label_0078;
Label_003E:
this.<>2__current = this.<line>5__1;
this.<>1__state = 2;
return true;
Label_005C:
if ((this.<line>5__1 = this.reader.ReadLine()) != null)
goto Label_003E;
this.<>m__Finally3(); // Disposal at end of file.
Label_0078:
flag = false;
fault
this.System.IDisposable.Dispose(); // Disposal due to fault.
return flag;
【讨论】:
【参考方案3】:只是为了更新:
在.net 5 中,它返回的IEnumerable
确实实现了IDisposable
,您可能需要在转换后调用Dispose
。但如果您阅读到文件末尾,它会自行处理。
【讨论】:
以上是关于File.ReadLines 啥时候释放资源的主要内容,如果未能解决你的问题,请参考以下文章