Параллельный.Еогеасп() и по каждому элементу(интерфейс IEnumerable.Методами asparallel())
Erg, я пытаюсь найти эти два метода в BCL с помощью рефлектора, но не могу их найти. В чем разница между этими двумя фрагментами?
A:
IEnumerable<string> items = ...
Parallel.ForEach(items, item => {
...
});
B:
IEnumerable<string> items = ...
foreach (var item in items.AsParallel())
{
...
}
существуют различные последствия использования одного над другим? (Предположим, что все, что я делаю в скобках тела обоих примеров является потокобезопасным.)
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
).