Параллельный.Еогеасп() и по каждому элементу(интерфейс IEnumerable.Методами asparallel())


Erg, я пытаюсь найти эти два метода в BCL с помощью рефлектора, но не могу их найти. В чем разница между этими двумя фрагментами?

A:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

существуют различные последствия использования одного над другим? (Предположим, что все, что я делаю в скобках тела обоих примеров является потокобезопасным.)

3 133

3 ответа:

они делают что-то совсем другое.

первый принимает анонимный делегат и запускает несколько потоков в этом коде параллельно для всех различных элементов.

второй не очень полезен в этом случае. В двух словах он предназначен для выполнения запроса на нескольких потоках, и объединить результат, и дать его снова в вызывающий поток. Таким образом, код инструкции foreach всегда остается в потоке пользовательского интерфейса.

это имеет смысл только если у вас что-то дорогое в запросе linq справа от AsParallel() звонок, типа:

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

разница в том, что B не параллельны. Единственная вещь AsParallel() делает то, что он обертывает вокруг IEnumerable, Так что при использовании методов LINQ используются их параллельные варианты. Обертка GetEnumerator() (которая используется за кулисами в foreach) даже возвращает результат исходной коллекции GetEnumerator().

кстати, если вы хотите посмотреть на методы в отражателе,AsParallel() находится в System.Linq.ParallelEnumerable класс System.Core сборка. Parallel.ForEach() находится в mscorlib сборка (пространство имен System.Threading.Tasks).

второй метод не будет параллельным правильный способ использования AsParallel () в вашем примере будет

IEnumerable<string> items = ...

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