为什么不是';t并行.对于每个运行多个线程

本文关键字:运行 于每个 线程 并行 为什么不 | 更新日期: 2023-09-27 18:20:50

今天我尝试对foreach语句进行一些优化,它适用于XDocument

优化前:

foreach (XElement elem in xDoc.Descendants("APSEvent").ToList())
{
    //some operations
}

优化后:

Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), elem =>
{
    //same operations
});

我看到Parallel.ForEach(...)中的.NET只打开了一个线程!结果Parallel的时间跨度大于标准foreach

为什么你认为.NET只打开了一个线程?因为锁定文件?感谢

为什么不是';t并行.对于每个运行多个线程

Parallel.ForEach在设计上可能会使用比请求更少的线程来获得更好的性能。根据MSDN[链接]:

默认情况下,Parallel.ForEach和Parallel.For方法可以使用可变数量的任务。这就是为什么,例如,ParallelOptions类具有MaxDegreeOfParallelism属性,而不是"MinDegreeOFParallelis"属性 其思想是,系统可以使用比请求更少的线程来处理循环

.NET线程池允许并行任务的工作线程数随时间变化,从而动态适应不断变化的工作负载 在运行时,系统会观察线程数量的增加是否会提高或降低总体吞吐量,并相应地调整工作线程的数量。

从问题描述中,没有任何内容可以解释为什么TPL没有生成更多线程。

在这个问题上没有任何证据表明这就是问题所在。这可以很容易地解决:在进入循环之前,您可以记录线程id,并且作为在循环中所做的第一件事

如果它总是相同的数字,则说明TPL未能生成线程。然后,您应该尝试不同版本的代码,以及哪些更改触发TPL序列化所有内容。其中一个原因可能是您的列表中有少量元素。TPL会对你的收藏进行分区,如果你只有几件物品,你可能只会得到一批。顺便说一下,这种行为是可配置的。

可能是你无意中锁定了循环,然后你会看到很多不同的数字,但没有加速。然后,简化代码,直到问题消失。

并行方式并不总是比"老式方式"快http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/c860cf3f-f7a6-46b5-8a07-ca2f413258dd

这样使用它:

int ParallelThreads = 10;
Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), new ParallelOptions() { MaxDegreeOfParallelism = ParallelThreads }, (myXDOC, i, j) =>
{
 //do whatever you want here 
});

是的,Document.Load(...)会锁定文件,由于线程之间的资源争用,TPL无法使用多个线程的能力。尝试将XML加载到Stream中,然后使用Parallel.For(...)

您碰巧有一个处理器吗?在这种情况下,TPL可以将线程的数量限制为一个。如果藏品很小,同样的情况也可能发生。试试更大的系列。有关如何确定并行度的更多详细信息,请参阅此答案。