TPL如何处理多个并行调用?
示例:我想并行处理两个不相关的集合。 (假设每个集合中的一个项目的处理需要很长时间)
目前我这样做:
Parallel.Invoke(() => Parallel.ForEach(collection1,...),
() => Parallel.ForEach(collection2,...))
这有效,但我很好奇TPL调度程序将如何处理3个单独的调用。
我应该采用不同的方式吗?
答案 0 :(得分:2)
首先要做的两件事:
如果您在Parallel.For / Parallel.ForEach工作负载(或循环委托中的任何类型的阻塞)中长时间运行迭代,则应始终使用ParallelOptions.MaxDegreeOfParallelism指定并发级别。这是因为并行循环实现针对更细粒度的工作负载进行了优化,并且当它们遇到长时间运行的迭代时,它们最终可能会注入额外的工作线程。
通过启动同步并行循环,您已经强制2个循环竞争CPU资源。因此,即使您没有长时间运行的迭代,通过限制每个循环的MaxDOP(实际上每个循环使用Environment.ProcessorCount / 2)来明确地对它们进行负载平衡是明智的。
回答您的原始问题:
... 3个单独的调用...
是的,TPL将处理3个或更多单独的Parallel.Invokes就好了。它甚至被优化为不会像这样在嵌套并行场景中浪费线程。
我应该采取不同的方式吗?
至少你应该像我上面解释的那样使用MaxDOP。但您可能希望根据这些策略选择不同的DOP策略: