平行的.ForEach和Cannot read from closed TextReader异常
本文关键字:from closed TextReader 异常 read Cannot ForEach | 更新日期: 2023-09-27 18:12:45
我有一个包含各种提要URL的文本文件。我正在使用以下代码读取集合(IEnumerable)中的所有URL:
var URLs = File.ReadLines(Path.GetFullPath(@"Resources'FeedList.txt"));
在下一行,我将打印总数:
Console.WriteLine("Total Number of feeds : {0}",URLs.Count());
之后我使用了parallel。ForEach构造,执行与每个URL对应的一些逻辑。下面是我使用的代码:
Parallel.ForEach(URLs, (url) =>
{
// Some business logic
});
问题是,我得到以下异常,只要我添加代码打印URL的数量,即调用的代码,Count()方法在URL对象上。例外:
Total Number of feeds : 78
Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.ObjectDisposedException: Cannot read from a closed TextReader.
at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadLine()
at System.IO.File.<InternalReadLines>d__0.MoveNext()
at System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable`1.InternalPartitionEnumerator.GrabNextChunk(Int32 requestedChunkSize)
at System.Collections.Concurrent.Partitioner.DynamicPartitionEnumerator_Abstract`2.MoveNext()
at System.Threading.Tasks.Parallel.<>c__DisplayClass32`2.<PartitionerForEachWorker>b__30()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass7.<ExecuteSelfReplicating>b__6(Object )
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 simpleBody, Action`2 bodyWi
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3
at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, Action`1 body)
at DiscoveringGroups.Program.Main(String[] args) in C:'Users'Pawan Mishra'Documents'Visual Studio 2010'Projects'ProgrammingCollectiveIntelligence'DiscoveringGroups'Pro
Press any key to continue . . .
如果我删除/注释掉这行,它打印计数值,Parallel。ForEach循环运行良好。
有没有人知道这里出了什么问题?
当你不需要的时候不要使用var
(或者当这个类型明显是多余的时候)。在这种情况下,它隐藏了正在发生的事情,并且您会对结果感到惊讶。
File.ReadLines
方法不读取所有行并返回一个集合,它返回一个枚举器,当您从中获取项时读取行。它返回的类型不是字符串数组,而是IEnumerable<string>
,如果您为变量指定了类型,就会注意到这一点:
string[] URLs = File.ReadLines(Path.GetFullPath(@"Resources'FeedList.txt"));
这会给出一个编译器错误,因为该方法没有返回一个数组,所以您会看到结果不是您所期望的。
当您在枚举器上使用Count()
方法时,它将读取文件中的所有行以便对它们进行计数,因此当您稍后再次尝试使用枚举时,它已经读取了所有行并关闭了TextReader
。
使用File.ReadAllLines
方法读取文件中的所有行,而不是获取枚举数:
string[] URLs = File.ReadAllLines(Path.GetFullPath(@"Resources'FeedList.txt"));
现在你可以多次使用这个数组