在使用
Parallel.ForEach()
时,有没有一种方法可以保证顺序?我正在遍历的集合需要保持其顺序,但我正在寻找一些性能改进。Parallel.ForEach()
时,有没有一种方法可以保证顺序?我正在遍历的集合需要保持其顺序,但我正在寻找一些性能改进。Parallel.ForEach(
list.AsParallel().AsOrdered(),
(listItems) => {<operations that you need to do>});
Parallel.Foreach(myData, ..., (d) =>
{
StringBuilder sb = new StringBuilder();
sb.Append(d);
// WriteLine sb?
});
Parallel.For
还是 Parallel.ForEach
,都不能保证您对 myData
内容的访问顺序。StringBuilder
中输出结果或构建完整字符串,则可能会阻塞共享资源,从而使并行循环的某些部分变为串行化。AsOrdered()
来达到目的。将此作为扩展方法完成
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);
}
use like:
var result = input.OrderedParallel(o => YourFunction(o));
对于任何寻找简单解决方案的人,我已经发布了两个扩展方法(一个使用PLINQ,另一个使用Parallel.ForEach
),作为回答以下问题的一部分:
不,ForEach 只用于顺序无关紧要的情况;请尝试使用 Parallel.For。