Parallel.ForEach () vs. foreach (IEnumerable <T> .AsParallel ())


143

На жаль, я намагаюся знайти ці два методи в BCL за допомогою Reflector, але не можу їх знайти. Яка різниця між цими двома фрагментами?

A:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

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

Відповіді:


148

Вони роблять щось зовсім інше.

Перший приймає анонімного делегата і паралельно виконує кілька потоків цього коду для всіх різних елементів.

Другий не дуже корисний у цьому сценарії. У двох словах, це покликане зробити запит на декількох потоках, а також об'єднати результат і знову надати виклику. Таким чином, код у операторі foreach завжди залишається на потоці інтерфейсу користувача.

Це має сенс лише в тому випадку, якщо ви робите щось дороге у запиті linq праворуч від AsParallel()дзвінка, наприклад:

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

У чому користь від простого паралельного передбачення на обчислювальній системі?
l - '' '''--------- '' '' '' '' '' '15

51

Різниця в тому, що B не паралельно. Єдине AsParallel(), що він обертається навколо IEnumerable, так що при використанні методів LINQ використовуються їх паралельні варіанти. Обгортка GetEnumerator()(яка використовується поза кадром у складі foreach) навіть повертає результат оригінальної колекції GetEnumerator().

BTW, якщо ви хочете подивитися на методи в Reflector, AsParallel()є в System.Linq.ParallelEnumerableкласі в System.Coreзборі. Parallel.ForEach()знаходиться у mscorlibзбірці (простір імен System.Threading.Tasks).


Що ви маєте на увазі під їх паралельними варіантами ...?
l --'''''--------- '' '' '' '' '' '15

2
@пунктуація. Наприклад, коли ви пишете .Select(), це називає, ParallelEnumerable.Select()а не нормально Enumerable.Select().
svick

50

Другий метод не буде паралельним правильним був би спосіб використання AsParallel () у вашому прикладі

IEnumerable<string> items = ...

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

3
Навіщо використовувати комбінацію аспаралелу разом з forall, а не просто передбачати?
l - '' '''--------- '' '' '' '' '' '15
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.