我喜欢ForEach()
方法,有时候它很方便,另一方面,对于并行方案我们有Parallel.ForEach()
。
因此,为了保持一致性,我创建了以下扩展方法:
public static class ParallelExtensions
{
public static void ForEachParallel<TSource>(this IEnumerable<TSource> source, Action<TSource> body)
{
Parallel
.ForEach(source, body);
}
}
然后useage会改变标准语法
Parallel
.ForEach(listOfThings, t => DoWork(t));
与扩展(更容易阅读):
listOfThings
.ForEachParallel(t => DoWork(t));
问题: 可以肯定的是,这种方法存在一些固有的错误吗?我担心的是,作为TPL的一部分创建这样的方法会非常容易,因为它不存在可能是有原因的吗?
答案 0 :(得分:1)
没有错,就像你写了一个&#34;替换者&#34;。但是要注意一些事情。
如果AggregateException
,则调用堆栈会在您的上方显示您的扩展程序。
处理空参数场景
public static class ParallelExtensions
{
public static void ForEachParallel<TSource>(this IEnumerable<TSource> source, Action<TSource> body)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
Parallel
.ForEach(source, body);
}
}
此外,在您的通话中,您可以使它更漂亮
而不是
listOfThings.ForEachParallel(t => DoWork(t));
你可以写
listOfThings.ForEachParallel(DoWork);
答案 1 :(得分:0)
我建议使用listOfThings.AsParallel().ForAll(x=> ...);
代替扩展方法,因为在这种情况下,您可以轻松使用ParallelEnumerable方法。
例如,您需要为有序数组运行ForEach
,使用之前必须对数组进行排序的扩展,然后运行ForEachParallel
。
使用.AsParallel().ForAll(x=> ...);
,您可以在.AsParallel()
和ForAll()
示例:
var a = new List<int>();
for(int i = 10000000; i > 0; i --)
a.Add(i);
DateTime start = DateTime.Now;
a.AsParallel().OrderBy(x=>x).ForAll(x => x = x ++);
var timeSpent = DateTime.Now - start;
start = DateTime.Now;
a.OrderBy(x => x).AsParallel().ForAll(x => x = x++);
var timeSpent2 = DateTime.Now - start;
Console.WriteLine(string.Format("1 - {0} 2 - {1}", timeSpent, timeSpent2));
Console.ReadLine();