Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1126. #ЗаметкиНаПолях #AsyncTips Parallel LINQ Задача: требуется выполнить параллельную обработку последовательности данных, чтобы сгенерировать другую их последовательность или обобщение этих данных. Решение Многие разработчики знакомы с технологией LINQ, позволяющей программировать вычисления с последовательностями, работающей по принципу вытягивания. Parallel LINQ (PLINQ) расширяет эту поддержку LINQ параллельной обработкой. PLINQ хорошо работает в потоковых сценариях, которые получают последовательность входных значений и производят последовательность выходных значений. Следующий простой пример просто умножает каждый элемент последовательности на 2 (в реальных сценариях выполняются гораздо более серьезные вычисления):
IEnumerable<int> Multiply(
 IEnumerable<int> vals)
{
  return vals.AsParallel()
    .Select(value => value * 2);
}

Пример может генерировать свои выходные значения в любом порядке; это поведение используется по умолчанию в Parallel LINQ. Также можно потребовать, чтобы сохранялся исходный порядок. В следующем примере обработка ведется параллельно, но с сохранением исходного порядка:
IEnumerable<int> Multiply(
 IEnumerable<int> vals)
{
  return vals.AsParallel()
    .AsOrdered().Select(value => value * 2);
}

Другое логичное применение Parallel LINQ — агрегирование или обобщение данных в параллельном режиме. В следующем примере выполняется параллельное суммирование:
int ParallelSum(IEnumerable<int> values)
{
  return values.AsParallel().Sum();
}

Класс Parallel хорошо подходит для многих сценариев, но код PLINQ получается более простым при агрегировании или преобразовании одной последовательности в другую. Следует помнить, что класс Parallel ведет себя более корректно с другими процессами в системе, чем PLINQ; этот фактор становится особенно существенным при выполнении параллельной обработки на серверной машине. PLINQ предоставляет параллельные версии многих операторов, включая фильтрацию (Where), проекцию (Select) и разные виды агрегирования, такие как Sum, Average и более общую форму Aggregate. В общем случае всё, что можно сделать в обычном LINQ, также можно сделать в параллельном режиме в PLINQ. В результате PLINQ становится отличным кандидатом для обработки существующего кода LINQ, который выиграл бы от выполнения в параллельном режиме. Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 4.