Parallel.ForEach适用于ThreadPool,默认情况下,TPL设置线程数,以便根据某些内部规则实现最高性能。但.Net是否考虑了并行或嵌套的“Parallel.Foreach”调用? 例如,假设.Net认为对于当前环境 10 线程是最佳选择,我们有:
Parallel.ForEach(collection1, (o1) => {Parallel.ForEach(collection2, (o2) => {...}})
它会产生 10 * 10 线程吗?
我发现的article让我觉得线程调度的“内部规则”是如此先进和动态,它可以合理地处理描述的案例。
答案 0 :(得分:3)
它不会生成线程而是生成任务。这两个循环将indirectly cooperate。这种合作并不完美,可能导致排队的任务超过必要/最佳。每个循环使一个副本排队等待调度程序。这允许调度程序启动比最佳任务更多的任务。
在任何情况下,这并不意味着100个线程竞争OS资源。线程池用于处理超额订阅。但是,它往往会产生比CPU更多的线程,以便能够处理阻塞。
尽量避免嵌套循环。通常,最好一次只有一个并行循环。例如,你可以这样做:
var items =
from o1 in collection1
from o2 in collection2
select new { o1, o2 };
Parallel.ForEach(items, ...);
如果你的架构需要嵌套循环,你可以拥有它们。