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