在IEnumerable迭代一次后,无法从关闭的textreader中读取
本文关键字:读取 textreader 迭代 IEnumerable 一次 | 更新日期: 2023-09-27 18:14:09
我有一个问题,"不能从一个关闭的文本阅读器"异常。我有一个程序,它应该从文件中获取数据,然后用它做一些有趣的事情,得到所有东西的时间跨度。
首先在一个函数中,我正在加载数据:
IEnumerable<string> SomeVariable;
SomeVariable = (from _Something in File.ReadLines(@"file location") select _Something.Split(' ')[1] );
在第二个函数中,我遍历它一次:
foreach (var _Something in SomeVariable)
{
SomeList.Add(_Something);
}
然而,在第三个函数中,当我试图再次运行它时:
foreach (var _Something in SomeVariable)
{
SomeOtherList.Add(_Something);
}
我得到异常:不能从一个关闭的textreader中读取。看起来在一次枚举之后,不再可能遍历somvariable。
这是IEnumerable本身的问题,还是与File有关?readline函数?我觉得每次我想遍历它时都从文件中重新加载数据是非常愚蠢的…
p。我做了研究,我意识到解决方案之一是把两个动作放在一个函数中,但不幸的是,这是大学程序,我必须这样写——我必须得到两个动作的单独时间跨度。
虽然您已经有了一个解决方法:当您忘记Dispose()
枚举器时,可能会发生这种情况,从而提示程序中的其他地方存在错误。
下面是一小段代码,它可靠地为我在第二个foreach
上抛出一个异常:
var lines = File.ReadLines(@"<...>");
var enumerator = lines.GetEnumerator();
foreach (var line in lines) { }
foreach (var line in lines) { }
是的,这将工作,如果你使用File.ReadAllLines(...)
代替,也如果你使用File.ReadLines(...).Select(...).ToList()
。然而,这不是一个完整的解决方案:异常的原因是enumerator
实现了IDisposable
,但是代码忘记了处理它。
var lines = File.ReadLines(@"<...>");
using (var enumerator = lines.GetEnumerator()) { } // <--- using statement
foreach (var line in lines) { }
foreach (var line in lines) { }
您应该找出代码中发生的地方,并以类似的方式修复它。问题不在你所展示的代码中。
您当然可以确保只读取文件一次。但是你应该把它和你得到的异常分开来考虑。
实际上,每次遍历SomeVariable
枚举时都是在重新加载数据。LINQ中的select
子句对应于Enumerable.Select
:
这个方法是通过延迟执行来实现的。立即返回值是一个对象,它存储执行操作所需的所有信息。此方法表示的查询直到使用
foreach
枚举对象时才执行[例如]。
这可能不是你想要的行为;您希望SomeVariable
热切地填充结果字符串列表。要实现这一点,您可以简单地在枚举对象上调用ToList
:
IList<string> SomeVariable =
(
from _Something in File.ReadLines(@"file location")
select _Something.Split(' ')[1]
).ToList();