使用时有没有办法保证顺序Parallel.ForEach()
?我循环的集合需要保持它的顺序,但我正在寻找一些性能改进。
问问题
13723 次
5 回答
9
为了保留顺序,您必须在将列表传递给 foreach 循环之前尝试对其进行排序,因为默认情况下 Parallel.Foreach 将列表视为无序。
例子 :
Parallel.ForEach(
list.AsParallel().AsOrdered(),
(listItems) => {<operations that you need to do>});
于 2018-04-26T19:42:20.393 回答
8
所以你有一个看起来像这样的声明?(根据您上面的评论)。
Parallel.Foreach(myData, ..., (d) =>
{
StringBuilder sb = new StringBuilder();
sb.Append(d);
// WriteLine sb?
});
这种方法存在许多问题。
- 既不
Parallel.For
也Parallel.ForEach
不会保证您对内容的myData
访问以任何特定顺序访问。 - 如果您是控制台上的方法或共享方法
StringBuilder
来输出结果或构建完整的字符串,那么您可能会阻塞共享资源,从而有效地序列化并行循环的部分。
如果没有看到您的代码的具体示例,很难说更多。根据您所做的事情,您也许可以使用AsOrdered()
PLINQ 中的订单保留来获得所需的位置。
请参阅此 MSDN 资源和
订购的 PLINQ ForAll
这将允许您根据输入顺序返回一个有序的结果集,但不保证实际处理的顺序。但是,如果并行查询阻塞了正文中的调用,则不太可能获得良好的性能。
于 2011-03-30T12:32:59.300 回答
1
将其作为扩展方法
public static IEnumerable<T1> OrderedParallel<T, T1>(this IEnumerable<T> list, Func<T, T1> action)
{
var unorderedResult = new ConcurrentBag<(long, T1)>();
Parallel.ForEach(list, (o, state, i) =>
{
unorderedResult.Add((i, action.Invoke(o)));
});
var ordered = unorderedResult.OrderBy(o => o.Item1);
return ordered.Select(o => o.Item2);
}
像这样使用:
var result = input.OrderedParallel(o => YourFunction(o));
希望这会为您节省一些时间。
于 2020-03-14T10:46:56.477 回答
0
对于任何寻求简单解决方案的人,我发布了 2 种扩展方法(一种使用 PLINQ,一种使用Parallel.ForEach
)作为对以下问题的回答的一部分:
于 2014-01-05T01:50:21.863 回答
-3
不,ForEach 仅用于顺序无关紧要的条件;试试Parallel.For
于 2010-11-09T16:43:42.423 回答