Parallel.ForEach () и foreach (IEnumerable <T>.AsParallel ()) - PullRequest
140 голосов
/ 24 сентября 2010

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

A:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

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

Ответы [ 3 ]

148 голосов
/ 24 сентября 2010

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

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

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

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

 var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));
49 голосов
/ 24 сентября 2010

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

оригинальной коллекции.

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

48 голосов
/ 24 сентября 2010

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

IEnumerable<string> items = ...

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