2011-02-16 69 views
4

我有一个报表构建类,它使用并行处理来构建一批800个左右的报表。更改了Parallel.ForEach行为?

直到昨天,它正在罚款下面的代码:

Parallel.ForEach(reports, report => { this.Build(report); }); 

注:用于调试目的,我exceuting从写在一个测试项目的测试代码。

昨天,它开始失败。用资源监视器挖掘一下,发现与qtagent32.exe(测试运行器)相关的线程数量不断增加,最终导致进程失败。它看起来好像突然变得阻塞了。

我能够用一个小的变化,以我的代码解决这个问题:

Parallel.ForEach(reports, new ParallelOptions { MaxDegreeOfParallelism = 4 }, report => { this.Build(report); }); 

但我仍然在想有什么改变?

+3

同一台机器?不同的机器? – 2011-02-16 08:41:54

+0

同一台机器,相同的代码... – 2011-02-16 09:03:32

回答

1

它只需要1个元素来慢一点。如果它真的是“相同的代码”,即相同的报告,它可能是数据库。多一点数据可以使查询变得更慢一些。

TPL位于ThreadPool的顶部,ThreadPool将缓慢地添加新线程。

假设您的某个报告比阈值(500毫秒)长,那么TP将创建一个额外的线程。如果您的报告争夺某些内容(最有可能的磁盘I/O),那么这个额外的线程将使其他报告更可能超出阈值。结果雪崩。

新的Fx4线程池比前一个更聪明,但它仍然是一个粗糙的启发式。您的MaxDegreeOfParallelism是正确的解决方案。