C# 改变了每个人的行为?

C# 改变了每个人的行为?,c#,parallel-processing,C#,Parallel Processing,我有一个报表构建类,它使用并行处理来构建一批800个左右的报表 直到昨天,它还可以使用以下代码正常工作: Parallel.ForEach(reports, report => { this.Build(report); }); 注意:出于调试目的,我将从测试项目中编写的测试中提取代码 昨天,它开始失败。使用ResourceMonitor进行挖掘后发现,与qtagent32.exe(测试运行程序)关联的线程数不断增加,最终导致进程失败。看起来好像有什么东西突然堵塞了 我可以通过对代码的一

我有一个报表构建类,它使用并行处理来构建一批800个左右的报表

直到昨天,它还可以使用以下代码正常工作:

Parallel.ForEach(reports, report => { this.Build(report); });
注意:出于调试目的,我将从测试项目中编写的测试中提取代码

昨天,它开始失败。使用ResourceMonitor进行挖掘后发现,与qtagent32.exe(测试运行程序)关联的线程数不断增加,最终导致进程失败。看起来好像有什么东西突然堵塞了

我可以通过对代码的一个小改动来解决这个问题:

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

但我仍然想知道是什么改变了?

只需要一个元素就可以稍微慢一点。如果它真的是“相同的代码”(即相同的报告),则可能是数据库。数据多一点,查询速度就会慢一点

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

支持一个报告所需时间超过阈值(500毫秒),然后TP将创建一个额外线程。如果您的报告竞争某些内容(很可能是磁盘I/O),那么额外的线程将使其他报告更有可能超过阈值。结果是雪崩


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

同一台机器?不同的机器?谢谢Henk,这些报告肯定在争夺磁盘I/O,而且我使用的是第三方PDF编写库(速度不太快),因此生成每个报告需要几秒钟的时间。数据访问不是问题,因为这是在生成报表之前完成的。