【问题标题】:Does Parallel.ForEach require AsParallel()Parallel.ForEach 是否需要 AsParallel()
【发布时间】:2010-02-16 01:29:03
【问题描述】:

ParallelEnumerable 有一个静态成员 AsParallel。如果我有一个IEnumerable<T> 并想使用Parallel.ForEach,这是否意味着我应该始终使用AsParallel

例如 这两个都正确吗(其他都一样)?

没有AsParallel:

List<string> list = new List<string>();
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)), f => list.Add(f));

AsParallel

List<string> list = new List<string>();
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)).AsParallel(), f => list.Add(f));

【问题讨论】:

    标签: .net-4.0 plinq task-parallel-library


    【解决方案1】:

    这取决于所调用的内容,它们是不同的问题。

    .AsParallel() 并行化枚举而不是任务委派。

    Parallel.ForEach 并行化循环,将任务分配给每个元素的工作线程。

    因此,除非您的源枚举从并行化中获益(例如,reader.Match(file) 很昂贵),否则它们是相等的。对于您的最后一个问题,是的,两者也是正确的。

    此外,您可能还想看看另一种结构,它可以稍微缩短它,但仍能最大限度地利用 PLINQ:

    GetFileList().Where(file => reader.Match(file)).ForAll(f => list.Add(f));
    

    【讨论】:

    • 嗯......到底什么是并行化枚举?或者至少如何将并行化与任务委派分开?
    • @dkackman .AsParallel() 准备好并行执行的计数,特别是在这种情况下.SelectMany() 的并行版本。考虑一个有大量 Where 子句但没有顺序的枚举,我们可以在尽可能多的内核上同时评估 where 子句,将枚举中的下一个提供给下一个可用线程,使其几乎快 n 倍。我们对该结果所做的事情也可以在之后以相同的方式处理,或者在一个线程中同步,或者在可用时跨内核分布,这就是 Parallel.ForEach.ForAll 部分,有意义吗?
    • 确实有道理。谢谢尼克。
    猜你喜欢
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 2012-01-15
    相关资源
    最近更新 更多