c# - C# 如何并行化 IEnumerable 的 IEnumerable?
问题描述
我有一个变量:
var contexts
设置后的位置是IEnumerable
. 这个对象的属性之一也是IEnumerable
我拥有的:
Parallel.ForEach(contexts.AsParallel(), (context) =>
{
Parallel.ForEach(context, (child) =>
{
});
});
但是VS抱怨第二个ForEach
解决方案
您正在尝试在这里应用太多嵌套并行性。
Parallel.ForEach( <-- #1
contexts.AsParallel(), <-- #2
(context) => {
Parallel.ForEach( <- #3
假设这是 CPU 绑定的工作,你真的不想这样做。这可能会创建太多需要映射到线程的任务,这将导致大量适得其反的上下文切换。
假设在最外层循环有足够数量的项目且体积相等,那么最好只在外层循环保持并行性:
Parallel.ForEach(
contexts,
context => { ...
(如果外层循环的项目数量不足以让所有核心保持忙碌,或者如果内层的项目分散IEnumerable
不均匀,会导致任务在不相等的时间完成,那么可以考虑使用@TheGeneral的使用思想contexts.SelectMany(c => c)
,即形式outer.SelectMany(o => o.Inner)
,在并行化之前将嵌套集合展平为一个更大的集合)。
如果您仍然发现并发性对于 CPU 密集型工作来说太高,您可以将其与目标计算机上的实际内核数相匹配,例如,如果您有 8 个可用内核:
Parallel.ForEach(
contexts,
new ParallelOptions { MaxDegreeOfParallelism = 8 },
context => { ...
但是,如果这将用于 IO 绑定工作,那么Parallel.For*
/.AsParallel
是错误的工具 - 使用异步并行工具,例如Task.WhenAll
.
推荐阅读
- javascript - 代码点火器。使用ajax按下按钮时如何从数据表中获取数据并将其显示为模态
- sql-server - SSIS:在 excel 中打开的 CSV 提取 - 一些字符串值显示为日期
- docker - 如何访问docker容器外的url
- c# - 微软商店。如何使用 C# 代码获取所有市场的所有价格?
- bash - 有没有办法使用变量并将其转换为以防万一?
- c# - TCP客户端连接错误,现有连接被远程主机强行关闭
- java - gremlin 中的模式匹配
- python - 我们可以在创建 Python 数据框时使用预定义的变量名称吗?
- python - 从python中的字典中提取日期时间
- python - Decimal number calculations in python