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

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

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

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

4 года назад
Открыть в
День 1413. #ЗаметкиНаПолях #AsyncTips Выполнение Кода с Помощью Планировщика. Окончание: Использование Планировщика Задача: требуется управлять выполнением отдельных фрагментов в параллельном коде. Решение После того как вы создадите экземпляр TaskScheduler (см. Создание Планировщика), можете включить его в набор параметров, передаваемых методу Parallel. Следующий код получает набор коллекций матриц, запускает несколько параллельных циклов и ограничивает общий параллелизм всех циклов одновременно независимо от количества матриц в каждом наборе:
void RotateMatrices(
 IEnumerable<IEnumerable<Matrix>> collections,
 float degrees)
{
  var schPair = new ConcurrentExclusiveSchedulerPair(
   TaskScheduler.Default,
   maxConcurrencyLevel: 8);
  var scheduler = schPair.ConcurrentScheduler;
  var opts = new ParallelOptions { 
   TaskScheduler = scheduler };

  Parallel.ForEach(
   collections,
   opts,
   matrices => Parallel.ForEach(
    matrices,
    opts,
    m => m.Rotate(degrees)));
}

Parallel.Invoke также получает экземпляр ParallelOptions, поэтому вы можете передать TaskScheduler при вызове Parallel.Invoke так же, как и для Parallel.ForEach. При выполнении динамического параллельного кода можно передать TaskScheduler непосредственно TaskFactory.StartNew или Task.ContinueWith. Передать TaskScheduler коду Parallel LINQ (PLINQ) невозможно. Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 13.