2011-06-08 71 views
3

我刚刚完成了我最复杂和功能最强的WinForms应用程序的日期。它加载一个列表中的任意数量的HTML文件,然后加载一个内容,使用一些正则表达式来匹配一些标签,并删除或替换它们(是的,是的,我见过this。它工作得很好,谢谢Cthulu),然后将它写入磁盘。将使用多个线程加速我的HTML文件处理应用程序?

但是,我注意到约200个文件需要大约30秒来处理,并且在第一个5-10秒之后程序报告为“不响应”。我假设做this guy did之类的东西并不明智,因为硬盘是瓶颈。

也许有可能将尽可能多的内存加载到内存中,然后使用线程处理每个内存,然后将它们加载到内存中?

至少,是否会创建一个独立于UI线程的工作线程来防止“无响应”问题? (This MSDN article covers what I was considering.

我想我是问多线程是否会提供任何速度改进,如果是的话,那么最好的方法是什么?

任何帮助或建议非常感谢!

+0

@亨克霍尔特曼我的道歉,WinForms。我将编辑这个问题来反映这一点。 – Omega192 2011-06-08 14:35:00

回答

3

是的,您应该先使用Backgroundworker将您的工作从GUI中分离出来。处理GUI事件永远不要花费太多时间。瞄准20ms,而不是20s。

然后,作为奖励,您可以看到处理(CPU密集型部分)是否可以拆分为独立作业并将其作为TPL任务执行。

没有足够的信息来说明是否应该如何做。

+0

+1对于TPL:伟大的库 – IAbstract 2011-06-08 14:28:31

+0

我在MSDN文章中读过了20ms规则。这是我第一次编写需要这么长时间的应用程序,因此后台工作者的概念对我来说是全新的。 我会研究TPL,这确实听起来不错。谢谢! – Omega192 2011-06-08 14:43:27

+0

查看[本页](http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx),特别是Completed事件中的if/else if/...。 – 2011-06-08 18:07:58

0

为什么不使用StreamReader.ReadAllLines()将每个文件读入数组,然后处理数组中的每个元素?

+0

我正在使用StreamReader.ReadToEnd()将文件内容读入单个字符串。你是否认为我应该创建几个线程,并让每个线程都在上述数组的单个元素上工作?我如何将修正后的元素的写入同步到磁盘? – Omega192 2011-06-08 14:39:23

-1

如果你在GUI线程中做了所有的处理,你的应用程序将会显示'没有响应',如果它需要很长时间。在我看来,您应该尽量不要在与GUI相同的线程中执行(广泛的)处理操作。 另外,你甚至可以为每个要处理的文件创建一个线程。只要单独的线程不需要来自彼此的任何数据,这就会大大提高速度。

+0

如果我要为每个文件创建一个线程,那么磁盘I/O操作会降低它们的速度。 – Omega192 2011-06-08 14:47:28

+0

但无论如何,永远不会超过单线程运行的一切权利? – 2011-06-08 14:58:29

+0

你不想为每个文件创建一个线程。 – IAbstract 2011-06-08 15:45:16

2

线程作业,任务等在大多数情况下会阻止主线程或主线程变得无法响应。不要为磁盘IO创建多个线程(显然)。我将专用一个工作线程来将文件从队列中取出并处理磁盘IO。否则,只有1或2个工作线程才能执行内存中的处理,而主线程可以保持响应。

+0

我一定会考虑做一些事情。谢谢! – Omega192 2011-06-08 14:46:38

2

首先,如果您希望程序保持响应,请将计算移至单独的线程(将其从UI线程中移除)。

实际性能改进取决于您拥有的处理器数量,而不是线程数量。

所以,如果你有P线程,你可以把工作P工作项目,并得到了一些改进工作。 (Amdahl's Law

您可以使用BackgroundWorker正确划分工作。:C# BackgroundWorker Tutorial

+0

我不知道BackgroundWorker甚至存在,谢谢你的链接! – Omega192 2011-06-08 14:45:58

+0

不是一个很好的教程。 Completed事件错误。 – 2011-06-08 18:05:31