День сто восемьдесят седьмой. #ЗаметкиНаПолях

Многопоточность.

6. Класс Parallel

Для реализации наиболее популярных сценариев посредством заданий создан класс System.Threading.Tasks.Parallel. Например, следующий код вызывает метод DoWork последовательно:

for(int i = 0; i < 1000; i++) DoWork(i);

Вместо этого можно распределить обработку между несколькими потоками пула:

Parallel.For(0, 1000, i => DoWork(i));



Аналогично метод foreach

foreach(var item in collection) DoWork(item);

можно заменить

Parallel.ForEach(collection, item => DoWork(item));



Параллельно запустить несколько методов можно с помощью метода Invoke:

Parallel.Invoke(

() => Method1(),

() => Method2(),

() => Method3());



Особенности:

1. Вызывающий поток также принимает участие в обработке и не блокируется, за исключением случаев, когда он заканчивает выполнение работы, а остальные потоки ещё нет.

2. Если какая-либо операция выбрасывает необработанное исключение, то вызванный вами метод класса Parallel выбросит исключение AggregateException (см. https://t.me/NetDeveloperDiary/221)

3. Использовать методы класса Parallel выгодно, лишь когда задания действительно могут выполняться параллельно, а также не обращаются к общим ресурсам.



Опции

Методам класса Parallel можно передать объект ParallelOptions со следующими свойствами:

- CancellationToken (токен отмены операции, по умолчанию CancellationToken.None)

- MaxDegreeOfParallelizm (максимальное количество рабочих элементов, по умолчанию -1 равно числу доступных процессоров)

- TaskScheduler – планировщик заданий.



Продолжение следует…



Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 26.