使用C#读取多个线程中的多个文件,慢!

时间:2009-11-16 04:46:09

标签: c#-3.0

我有一个Intel Core 2 Duo CPU,我正在从我的C:驱动器中读取3个文件并显示 从文件到屏幕上的EditBox的一些匹配值。整个过程需要2分钟。然后我想在一个单独的线程中处理每个文件,然后整个过程需要2.30分钟!比单线程处理多30秒。

我期待相反的方向!我可以在CPU使用历史中看到两个图表。有一个请向我解释发生了什么? 这是我的代码片段。

 foreach (FileInfo file in FileList)
{

   Thread t  = new Thread(new ParameterizedThreadStart(ProcessFileData));
   t.Start(file.FullName);  

}

其中processFileData是处理文件的方法。

谢谢!

4 个答案:

答案 0 :(得分:11)

问题的根源在于文件位于同一个驱动器上,与双核处理器不同,您的硬盘驱动器一次只能做一件事。

如果同时读取两个文件,磁盘磁头将从一个文件跳到另一个文件,然后再返回。鉴于您的硬盘驱动器可以在大约40秒内读取每个文件,现在它有额外的开销,即在读取期间多次在三个单独的文件之间移动磁盘头。

从单个硬盘驱动器读取多个文件的最快方法是在一个线程中完成所有操作并一个接一个地读取它们。这样,磁头每次读取文件时(一开始)只移动一次,而不是每次读取多次。

要优化此过程,您需要更改逻辑(您是否真的需要读取所有三个文件的全部内容?)。或者购买更快的硬盘/将3个文件放在三个不同的硬盘中并使用线程/使用raid。

答案 1 :(得分:3)

如果您使用多个线程从磁盘读取,那么当每个线程从驱动器的不同部分读取时,磁盘磁头将从磁盘的一部分弹回到另一部分。正如您所见,这可以显着降低吞吐量。

出于这个原因,让所有磁盘访问都通过一个线程通常更好一点,以帮助最小化磁盘搜索。

如果您的任务受I / O限制,并且需要经常运行,您可能会查看像“contig”这样的工具,以确保磁盘上文件的布局是优化/连续的。

答案 2 :(得分:1)

如果您的处理主要是IO绑定和CPU绑定,那么它需要花费相同的时间甚至更多。

你如何比较这些文件?您应该考虑应用程序的瓶颈是什么? IO输出/输入,CPU,内存......

多线程只对CPU绑定处理很有意义。即复杂计算,内存中数据的比较,排序等......

答案 3 :(得分:0)

由于您的进程是IO绑定的,您应该让操作系统为您执行线程处理。查看FileStream.BeginRead()以获取如何排队读取的示例。您的EndRead()方法可以启动您的下一个请求,以读取指向自身的下一个数据块,以处理每个后续已完成的块。

此外,随着您创建其他线程,操作系统必须管理更多线程。如果选择不同的CPU来处理已完成的读取,那么您已经丢失了线程所在的所有CPU缓存。

正如您所发现的那样,只能通过添加线程来“加速”应用程序。