【问题标题】:Parallel.ForEach() vs. foreach(IEnumerable<T>.AsParallel())Parallel.ForEach() 与 foreach(IEnumerable<T>.AsParallel())
【发布时间】:2011-04-16 22:36:38
【问题描述】:

呃,我正在尝试使用 Reflector 在 BCL 中找到这两种方法,但找不到它们。这两个sn-ps有什么区别?

答:

IEnumerable<string> items = ...

Parallel.ForEach(items, item => {
   ...
});

乙:

IEnumerable<string> items = ...

foreach (var item in items.AsParallel())
{
   ...
}

使用其中一种会有不同的后果吗? (假设我在两个示例的括号中所做的任何事情都是线程安全的。)

【问题讨论】:

    标签: c# .net multithreading parallel-processing parallel.foreach


    【解决方案1】:

    他们做的事情完全不同。

    第一个接受匿名委托,并在此代码上为所有不同的项目并行运行多个线程。

    第二个在这种情况下不是很有用。简而言之,它旨在对多个线程进行查询,并将结果组合起来,然后再次将其提供给调用线程。因此,foreach 语句中的代码始终保留在 UI 线程上。

    只有在 AsParallel() 调用右侧的 linq 查询中执行昂贵的操作时才有意义,例如:

     var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));
    

    【讨论】:

    • 与简单地在 computefibonacci 上执行并行 foreach 相比有什么好处?
    【解决方案2】:

    第二种方法不会并行,在您的示例中使用 AsParallel() 的正确方法是

    IEnumerable<string> items = ...
    
    items.AsParallel().ForAll(item =>
    {
        //Do parallel stuff here
    });
    

    【讨论】:

    • 为什么要结合使用 asparallel 和 forall 而不是简单的 foreach?
    【解决方案3】:

    不同的是,B 不是平行的。 AsParallel() 所做的唯一事情是它包裹了 IEnumerable,因此当您使用 LINQ 方法时,会使用它们的并行变体。包装器的GetEnumerator()(在foreach 的幕后使用)甚至返回原始集合的GetEnumerator() 的结果。

    顺便说一句,如果您想查看 Reflector 中的方法,AsParallel()System.Core 程序集中的 System.Linq.ParallelEnumerable 类中。 Parallel.ForEach()mscorlib 程序集中(命名空间 System.Threading.Tasks)。

    【讨论】:

    • 你的意思是……他们的平行变种被使用了……?
    • @punctuation 例如,当您编写.Select() 时,它调用ParallelEnumerable.Select() 而不是正常的Enumerable.Select()
    猜你喜欢
    • 1970-01-01
    • 2015-11-19
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多