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

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

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

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

5 лет назад
Открыть в
День 1102. #ЗаметкиНаПолях #AsyncTips Параллельный Вызов Задача: имеется набор методов, которые должны вызываться параллельно. Эти методы (в основном) независимы друг от друга. Решение Класс Parallel содержит простой метод Invoke, спроектированный для таких сценариев. В следующем примере массив разбивается надвое, и две половины обрабатываются независимо:
void Process(double[] arr)
{
  Parallel.Invoke(
    () => ProcessPartial(arr, 0, arr.Length/2),
    () => ProcessPartial(arr, arr.Length/2, arr.Length)
  );
}
void ProcessPartial(double[] array, int begin, int end)
{
  // Обработка, интенсивно использующая процессор...
}

Методу Parallel.Invoke также можно передать массив делегатов, если количество вызовов неизвестно до момента выполнения:
void DoActions(Action action)
{
  Action[] actions = Enumerable.Repeat(action, 20).ToArray();
  Parallel.Invoke(actions);
}

Parallel.Invoke поддерживает отмену, как и другие методы класса Parallel:
void DoActions(Action action, CancellationToken token)
{
  Action[] actions = Enumerable.Repeat(action, 20).ToArray();
  Parallel.Invoke(
    new ParallelOptions { CancellationToken = token },
    actions);
}

Метод Parallel.Invoke — отличное решение для простого параллельного вызова. Отмечу, что он уже не так хорошо подходит для ситуаций, в которых требуется активизировать действие для каждого элемента входных данных (для этого лучше использовать Parallel.ForEach), или если каждое действие производит некоторый вывод (вместо этого следует использовать Parallel LINQ). Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 4.