SlideShare a Scribd company logo
1 of 29
Download to read offline
Многопоточное
программирование на C#,
путевые заметки
Дмитрий Литичевский
ByndyuSoft
11-я конференция .NET разработчиков
31 октября 2015
dotnetconf.ru
2
О себе
 Team lead в компании ByndyuSoft
 Аспирант ЧелГУ, дискретная математика и
математическая кибернетика
 Любитель вселенной Warhammer 40000
В МРАЧНОЙ ТЬМЕ ДАЛЁКОГО
БУДУЩЕГО ЕСТЬ ТОЛЬКО
ВОЙНА...
3
Прежде чем начать
Зачем нам все это?
Хотим эффективно использовать
имеющиеся ресурсы.
Когда это сработает?
Обрабатывается поток
ресурсоемких слабосвязанных
друг с другом задач
4
Асинхронная обработка
Одним из способов ускорить приложения является
асинхронный запуск длительных операций, мы
запускаем ее и не ждем завершения
Возможные примеры:
1. Cетевые запросы;
2. Доступ к диску;
3. Сложные вычисления.
l
Основное различие заключается в том, в каком потоке
выполняется запущенная длительная операция.
5
Что предлагает нам C#
Event-based Asynchronous Pattern (EAP)
private void DownloadContentFromUrl(Uri uri)
{
var client = new WebClient();
client.DownloadStringCompleted += OnDownloadStringCompleted;
client.DownloadStringAsync(uri);
}
Интерфейс IAsyncResult
private void LookupHostName()
{
Dns.BeginGetHostAddresses("dotnetconf.ru", OnNameResolved, null);
}
private void OnNameResolved(IAsyncResult ar)
{
var addresses = Dns.EndGetHostAddresses(ar);
}
Task-based Asynchronous Pattern (TAP)
6
Договор с TAP
Не допустимы ref и out параметры методов.
Метод должен возвращать значение типа Task<T>, Task или
void в зависимости от возвращаемого значения синхронного
метода.
Исключение из-за ошибки в параметрах вызова метода можно
возбуждать непосредственно (используя оператор throw),
остальные исключения следует помещать в объект Task.
Единый API для работы с асинхронными операциями, что
позволяет реализовать на уровне компилятора такие средства
как async/await.
7
Примеры использования TAP
var x = await Task.Run(() => SolveSystem(a, b));
Task t = Task.Factory.StartNew(() => SolveSystem(a, b),
cts.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Current);
private async Task DownloadPageAsync(string uri)
{
using (var client = new HttpClient())
using (var response = await client.GetAsync(uri))
using (var content = response.Content)
{
var result = await content.ReadAsStringAsync();
// Processing
}
}
8
TAP, обработка ошибок
Методы возвращают Task илиTask<T>, ожидаем простой
таск используя await.
try
{
var pageContent = await webClient.DownloadStringTaskAsync(uri);
// Processing
}
catch (Exception ex)
{
// Handling
}
Исключение возбуждается там, где находится оператор
await, перехватывается, все красиво и здорово.
9
TAP, обработка ошибок
Методы возвращают Task илиTask<T>, ожидаем
результат используя методы Wait, WaitAll, WaitAny
try
{
var task = webClient.DownloadStringTaskAsync(uri);
task.Wait();
// Processing
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions) {/*Handling*/ }
}
AggregateException возбуждается в месте вызова
Wait, WaitAll, WaitAny, возникшие исключения
находятся в свойстве InnerExceptions.
10
TAP, обработка ошибок
Методы оформлены по стандарту, ожидаем составной таск
var allTask = Task.WhenAll(tasks);
try
{
await allTask;
}
catch
{
foreach (var ex in allTask.Exception.InnerExceptions)
{
// Handling
}
}
При выполнении тасков может возникать несколько исключений, но в
операторе await возбуждается одно из них. Все исключения могут
быть найдены в коллекции InnerExceptions объекта класса
AggregateException, лежащего в свойстве Exception
ожидаемого таска.
11
TAP, обработка ошибок
Асинхронный метод возвращает Task или void, мы не хотим или не можем
дождаться его завершения. Тогда мы можем:
1. Реализовать обработку ошибок внутри самой операции;
2. Если метод все же возвращает таск, то добавить к нему Continuation
var task = DownloadPageAsync("http://dotnetconf.ru/");
task.ContinueWith(t => t.Exception.Handle(e =>
{
// Handling
return true;
}),
TaskContinuationOptions.OnlyOnFaulted);
private async Task DownloadPageAsync(string uri)
{
using (var webclient = new WebClient())
{
var content = await webclient.DownloadStringTaskAsync(uri);
// Processing
}
}
12
TAP, отмена операции
Используется классы CancellationToken и CancellationTokenSource
Способы прерывания:
1. По прошествии определенного времени с помощью CancelAfter
2. В ручную с помощью Cancell
using (var cts = new CancellationTokenSource())
{
cts.CancelAfter(TimeSpan.FromMilliseconds(100));
try
{
var task = DownloadPageAsync("http://dotnetconf.ru/", cts.Token);
task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
// Handling
}
catch (AggregateException)
{
// Handling
}
}
13
TAP, отмена операции
Обработка сводится к периодической проверке вызываемым кодом
свойства IsCancellationRequested и вызову метода
ThrowIfCancellationRequested объекта CancellationToken.
Task.Run(() =>
{
for (var i = 0; i < n; i++)
{
// Calculations
token.ThrowIfCancellationRequested();
}
}, token)
.Wait();
Если требуется освобождение ресурсов, то мы можем периодически
проверять флаг IsCancellationRequested.
14
Типы многопоточная обработки
Организацию многопоточной обработки данных в
приложениях можно разделить на два типа:
1. Задачи заранее известны, организовывать их обработку
будем с использованием библиотек TPL или PLINQ.
2. Задачи генерируются в процессе обработки, модель
producer and consumer будем реализовывать при
помощи класса ThreadPool или библиотеки Rx.
Данная классификация является условной призвана помочь
автору структурировать остальную часть доклада.
15
TPL, теория
TPL содержит класс Parallel, возможности которого аналогичны
библиоке OpenMP для С++. Для распараллеливания циклов в классе
объявлены три перегруженных метода:
1. For, организует распаралеленный цикл for, в качестве одного из
аргументов передается тело цикла.
2. ForEach, организует распаралеленную обработку коллекций,
реализующих интерефейс IEnumerable<T>, в качестве одного из
аргументов передается тело цикла.
3. Invoke, организует параллельный вызов экземпляров Action,
переданных в качестве параметров.
Ошибки, возникшие и не перехваченные в обрабатывающих потоках,
помещаются в экземпляр AggregateException. Вызвавший
методы поток блокируется до завершения обработки.
16
TPL, примеры
Parallel.ForEach(orders,
new ParallelOptions {MaxDegreeOfParallelism = threadsCount},
UpdateOrder);
Parallel.Invoke(
() => DeleteSubjects(orderId),
() => DeleteDocuments(orderId),
() => DeleteSuppliers(orderId)
);
17
TPL, нюансы
Использование экземпляра ParallelOptions позволяет более полно
контролировать выполняемые операции:
1. MaxDegreeOfParallelism, регулирует количество потоков,
которые будут использованы для обработки.
2. CancellationToken, токен, используемый для отмены
запускаемой операции.
3. TaskScheduler, управляет запуском потоков обработки задач.
Использование класса Partitioner позволяет управлять разбиением задач
между потоками и их балансировкой. TPL может динамически распределять
нагрузку между потоками или же может распределить их некоторым
образом перед стартом выполнения расчетов и не менять по ходу
обработки, это настраивается с помощью Partitioner.Create.
var tasks = Enumerable.Range(1, 100).ToArray();
Parallel.ForEach(Partitioner.Create(tasks, true), ProcessItem);
18
PLINQ, теория
PLINQ является реализацией LINQ, распеределенно выполняющей
запросы. Для этого были добавлены классы
ParallelEnumerable, ParallelQuery, ParallelQuery<T>, а
также нескольких других. Не все операторы LINQ реализованы в
PLINQ.
Этапы выполнения запроса:
1. Выбор модели выполнения (параллельно или последовательно),
будем считать, что запрос будет выполняться параллельно.
2. Распределение задач между потоками.
3. Запуск выполнения запроса;
4. Слияние результатов работы отдельных потоков в вызывающем
потоке;
5. Итерация по результатам запроса.
Ошибки, возникшие и не перехваченные в обрабатывающих потоках,
помещаются в экземпляр AggregateException.
19
PLINQ, пример
var tradeItemsForUpdate = tradeItems
.AsParallel()
.WithDegreeOfParallelism(_threadsCount)
.Where(UpdateNeeded)
.ToArray();
var range = Enumerable.Range(0, 100000000).ToArray();
var partitioner = Partitioner.Create(range, true);
var query = partitioner.AsParallel().Select(Calc);
Для написания запросов с использованием PLINQ достаточно вызвать
метод разширения ParallelEnumerable.AsParallel после
чего запрос будет строиться с использованием методов PLINQ.
20
PLINQ, нюансы
В случае 100% уверенности в том, что распараллеливание запроса
принесет прирост в скорости, можно заставить среду исполнять его
параллельно, вызвав метода WithExecutionMode, вызванного c
параметром ParallelExecutionMode.ForceParallelism.
var ordersForUpdate = orders.AsParallel()
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.Where(UpdateNeeded)
.ToArray();
Разбиение задач между потоками настраивается. Для этого
используется уже описанный ранее класс Partitioner и его
метод Create. С его помощью можно включить динамическую
балансировку задач, отключенную по умолчанию для массивов и
коллекций, реализующих Ilist. Если описанного недостаточно, то
можно реализовать свой Partitioner согласно требованиям TPL.
21
PLINQ, нюансы
В отличии от первых двух пунктов цепи выполнения запроса, существует
гораздо больше возможностей влияния на его выполнение. Допустимо
следующее:
1. Управлять числом обрабатывающих потоков с помощью метода
WithDegreeOfParallelism.
2. Управлять досрочным прекращением операций с помощью метода
WithCancellation, передав в качестве параметра экземпляр
CancellationToken.
3. Управлять учетом порядка записей исходной коллекции при генерации
результатов с помощью методов AsOrdered/AsUnordered.
var ordersForUpdate = orders.AsParallel()
.AsOrdered()
.WithDegreeOfParallelism(threadsCount)
.WithCancellation(cts.Token)
.Where(UpdateNeeded)
.ToArray();
22
PLINQ, нюансы
Для обработки результатов запросов из примеров необходимо
слить вместе результаты отдельных потоков и отдать их
вызвавшему. Это настраивается при помощи метода
WithMergeOptions, доступны следующие варианты:
1. FullyBuffered, результаты полностью буферизуются.
2. AutoBuffered, результаты частично буферизуются.
3. NotBuffered, результаты не буферизуются.
var ordersForUpdate = orders.AsParallel()
.WithMergeOptions(ParallelMergeOptions.FullyBuffered)
.Where(UpdateNeeded);
foreach (var order in ordersForUpdate)
UpdateOrder(order);
23
PLINQ, нюансы
Если обработка результатов запроса может быть выполнена
параллельно и ее порядок не важен, то можно
воспользоваться методом ForAll, передав в него тело цикла,
сэкономив на слиянии промежуточных результатов.
orders.AsParallel()
.ForAll(x =>
{
if(UpdateNeeded(x))
UpdateOrder(x);
});
24
Использование ThreadPool
Простейший вариант параллельной обработки — это использование
метода QueueUserWorkItem класса ThreadPool.
while (true)
{
var message = GetMessage(queueName);
if (message != null)
ThreadPool.QueueUserWorkItem(DispatchMessage, message);
else
Thread.Sleep(30000);
}
25
Использование ThreadPool
Для ограничения числа отправляемых в ThreadPool задач, например, при
чтении из очереди, можно использовать Semaphore.
_semaphore.WaitOne();
ThreadPool.QueueUserWorkItem(DispatchMessage, message);
private void DispatchMessage(object state)
{
var message = (MessageInfo)state;
try
{
OnMessageReceive(this, message);
}
finally
{
_semaphore.Release();
}
}
26
Использование Rx
Состоит из интерфейсов Iobservable<T> и IObserver<T>, включенных в
.NET начиная с версии 4 и nuget пакета Rx-Main.
public interface IObservable<T>
{
IDisposable Subscribe(IObserver<T> observer);
}
public interface IObserver<T>
{
void OnNext(T value);
void OnCompleted();
void OnException(Exception error);
}
Rx предлагает другую модель обработки данных, push вместо pull, о новых
событиях нас будет уведомлять сама библиотека.
27
Использование Rx
Библиотека позволяет настраивать, в каких потоках будут выполняться методы
Observer'а. Для этих целей служат методы SubscribeOn и ObserveOn
класса Observable.
_customerService.GetCustomers()
.SubscribeOn(Scheduler.TaskPool)
.Subscribe(Customers.Add);
Метод ObserveOn определяет какой Scheduler'е будет использоваться для
вызовов методов Observer'а. Метод SubscribeOn определяет где будет
порождаться и обрабатываться уведомления для Observer'ов. Интересны
следующие Scheduler'ы:
1. Scheduler.NewThread, обработка будет запущена в отдельном потоке.
2. Scheduler.ThreadPool, обработка будет запущена в ThreadPool.
3. Scheduler.TaskPool, обработка будет запущена в TaskPool.
28
Литература и примеры
Литература:
1. https://msdn.microsoft.com/ru-ru/library/dd997415(v=vs.110).aspx
2. https://msdn.microsoft.com/ru-ru/library/hh524395.aspx
3. https://msdn.microsoft.com/en-us/library/jj155759.aspx
4. http://habrahabr.ru/post/168669/
5. https://msdn.microsoft.com/en-us/library/dd997425(v=vs.110).aspx
6. https://msdn.microsoft.com/en-us/library/dd997411.aspx
7. http://stackoverflow.com/questions/15773008/reactive-framework-as-
message-queue-using-blockingcollection
8. http://www.introtorx.com/content/v1.0.10621.0/15_SchedulingAndThreading.ht
ml
9. Асинхронное программирование в C# 5.0, Алекс Дэвис
10. Concurrency in C# Cookbook, Stephen Cleary
11. C# in depth, Jon Skeet
Примеры: github
29
Спасибо за внимание
Литичевский Дмитрий
ByndyuSoft
dmitry.litichevskiy@byndyusoft.com
vk

More Related Content

What's hot

Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверPlatonov Sergey
 
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with SeleniumOSLL
 
Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - MultithreadingNoveo
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Noveo
 
Обзор Linux Control Groups
Обзор Linux Control GroupsОбзор Linux Control Groups
Обзор Linux Control GroupsOSLL
 
Пространства имен Linux (linux namespaces)
Пространства имен Linux (linux namespaces)Пространства имен Linux (linux namespaces)
Пространства имен Linux (linux namespaces)OSLL
 
Kubernetes
KubernetesKubernetes
KubernetesSQALab
 
Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решенийVladimir Sitnikov
 
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...Ontico
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Yandex
 
Continuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedContinuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedAleksandr Tarasov
 
Григорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммыГригорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммыYandex
 
Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...SQALab
 
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияSQALab
 
Software engineering seminars: gradle
 Software engineering seminars: gradle Software engineering seminars: gradle
Software engineering seminars: gradleSemen Martynov
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Dima Dzuba
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Frameworkbeloslab
 
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с MavenКурс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven7bits
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Fwdays
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Yulia Tsisyk
 

What's hot (20)

Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with Selenium
 
Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - Multithreading
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
 
Обзор Linux Control Groups
Обзор Linux Control GroupsОбзор Linux Control Groups
Обзор Linux Control Groups
 
Пространства имен Linux (linux namespaces)
Пространства имен Linux (linux namespaces)Пространства имен Linux (linux namespaces)
Пространства имен Linux (linux namespaces)
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решений
 
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"
 
Continuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedContinuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons Learned
 
Григорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммыГригорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммы
 
Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...
 
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестирования
 
Software engineering seminars: gradle
 Software engineering seminars: gradle Software engineering seminars: gradle
Software engineering seminars: gradle
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Framework
 
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с MavenКурс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
 

Viewers also liked

Альтернативные способы изучения программирования с нуля
Альтернативные способы изучения программирования с нуляАльтернативные способы изучения программирования с нуля
Альтернативные способы изучения программирования с нуляCOMAQA.BY
 
Инструменты программиста
Инструменты программистаИнструменты программиста
Инструменты программистаAndrew Fadeev
 
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...Mikhail Kurnosov
 
Внутреннее устройство GC
Внутреннее устройство GCВнутреннее устройство GC
Внутреннее устройство GCtym32167
 
Как грабить корованы
Как грабить корованыКак грабить корованы
Как грабить корованыDotNetConf
 
Антон Нехаев - Многопоточное и распределенное программирование
Антон Нехаев - Многопоточное и распределенное программированиеАнтон Нехаев - Многопоточное и распределенное программирование
Антон Нехаев - Многопоточное и распределенное программированиеDataArt
 

Viewers also liked (6)

Альтернативные способы изучения программирования с нуля
Альтернативные способы изучения программирования с нуляАльтернативные способы изучения программирования с нуля
Альтернативные способы изучения программирования с нуля
 
Инструменты программиста
Инструменты программистаИнструменты программиста
Инструменты программиста
 
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...
Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming...
 
Внутреннее устройство GC
Внутреннее устройство GCВнутреннее устройство GC
Внутреннее устройство GC
 
Как грабить корованы
Как грабить корованыКак грабить корованы
Как грабить корованы
 
Антон Нехаев - Многопоточное и распределенное программирование
Антон Нехаев - Многопоточное и распределенное программированиеАнтон Нехаев - Многопоточное и распределенное программирование
Антон Нехаев - Многопоточное и распределенное программирование
 

Similar to Многопоточное программирование на C#, путевые заметки

C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееGetDev.NET
 
обработка исключений в Java
обработка исключений в Javaобработка исключений в Java
обработка исключений в Javametaform
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesPlatonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesPlatonov Sergey
 
8. java lecture threads
8. java lecture threads8. java lecture threads
8. java lecture threadsMERA_school
 
Svitla .Net meetup in Kiev, Anzhiiak Oleksii
Svitla .Net meetup in Kiev, Anzhiiak OleksiiSvitla .Net meetup in Kiev, Anzhiiak Oleksii
Svitla .Net meetup in Kiev, Anzhiiak OleksiiSvitla Systems Inc.
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализацияYandex
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времениTatyanazaxarova
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage CollectorOlexandra Dmytrenko
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1Michael Karpov
 
Java весна 2014 лекция 5
Java весна 2014 лекция 5Java весна 2014 лекция 5
Java весна 2014 лекция 5Technopark
 
Lecture1: Introduction to Parallel Computing
Lecture1: Introduction to  Parallel ComputingLecture1: Introduction to  Parallel Computing
Lecture1: Introduction to Parallel ComputingAndrii Rodionov
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...Fwdays
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияRuslan Shevchenko
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularizationIvan Krylov
 

Similar to Многопоточное программирование на C#, путевые заметки (20)

C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущее
 
обработка исключений в Java
обработка исключений в Javaобработка исключений в Java
обработка исключений в Java
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
8. java lecture threads
8. java lecture threads8. java lecture threads
8. java lecture threads
 
Svitla .Net meetup in Kiev, Anzhiiak Oleksii
Svitla .Net meetup in Kiev, Anzhiiak OleksiiSvitla .Net meetup in Kiev, Anzhiiak Oleksii
Svitla .Net meetup in Kiev, Anzhiiak Oleksii
 
Async
AsyncAsync
Async
 
Luxoft async.net
Luxoft async.netLuxoft async.net
Luxoft async.net
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1
 
Java весна 2014 лекция 5
Java весна 2014 лекция 5Java весна 2014 лекция 5
Java весна 2014 лекция 5
 
Lecture1: Introduction to Parallel Computing
Lecture1: Introduction to  Parallel ComputingLecture1: Introduction to  Parallel Computing
Lecture1: Introduction to Parallel Computing
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...
Александр Поштарук "Use-case оператора replyWhen из Rx.JS на примере Ангулар ...
 
Step 7
Step 7Step 7
Step 7
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестирования
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularization
 

More from DotNetConf

Как анимировать тысячи объектов на карте и не подвесить браузер
Как анимировать тысячи объектов на карте и не подвесить браузерКак анимировать тысячи объектов на карте и не подвесить браузер
Как анимировать тысячи объектов на карте и не подвесить браузерDotNetConf
 
Делаем очередь поверх Кассандры
Делаем очередь поверх КассандрыДелаем очередь поверх Кассандры
Делаем очередь поверх КассандрыDotNetConf
 
К искусству записи пользовательских историй
К искусству записи пользовательских историйК искусству записи пользовательских историй
К искусству записи пользовательских историйDotNetConf
 
Кроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и противКроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и противDotNetConf
 
Быстрый бэкенд с parse.com
Быстрый бэкенд с parse.comБыстрый бэкенд с parse.com
Быстрый бэкенд с parse.comDotNetConf
 
Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?DotNetConf
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?DotNetConf
 
Платформа Apache Hadoop
Платформа Apache HadoopПлатформа Apache Hadoop
Платформа Apache HadoopDotNetConf
 
Робототехника для прикладных программистов
Робототехника для прикладных программистовРобототехника для прикладных программистов
Робототехника для прикладных программистовDotNetConf
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаDotNetConf
 
Inversion of Control в .NET
Inversion of Control в .NETInversion of Control в .NET
Inversion of Control в .NETDotNetConf
 
Введение в реактивный .NET
Введение в реактивный .NETВведение в реактивный .NET
Введение в реактивный .NETDotNetConf
 
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...DotNetConf
 
Машинное обучение на платформе .NET
Машинное обучение на платформе .NETМашинное обучение на платформе .NET
Машинное обучение на платформе .NETDotNetConf
 

More from DotNetConf (14)

Как анимировать тысячи объектов на карте и не подвесить браузер
Как анимировать тысячи объектов на карте и не подвесить браузерКак анимировать тысячи объектов на карте и не подвесить браузер
Как анимировать тысячи объектов на карте и не подвесить браузер
 
Делаем очередь поверх Кассандры
Делаем очередь поверх КассандрыДелаем очередь поверх Кассандры
Делаем очередь поверх Кассандры
 
К искусству записи пользовательских историй
К искусству записи пользовательских историйК искусству записи пользовательских историй
К искусству записи пользовательских историй
 
Кроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и противКроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и против
 
Быстрый бэкенд с parse.com
Быстрый бэкенд с parse.comБыстрый бэкенд с parse.com
Быстрый бэкенд с parse.com
 
Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
 
Платформа Apache Hadoop
Платформа Apache HadoopПлатформа Apache Hadoop
Платформа Apache Hadoop
 
Робототехника для прикладных программистов
Робототехника для прикладных программистовРобототехника для прикладных программистов
Робототехника для прикладных программистов
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
 
Inversion of Control в .NET
Inversion of Control в .NETInversion of Control в .NET
Inversion of Control в .NET
 
Введение в реактивный .NET
Введение в реактивный .NETВведение в реактивный .NET
Введение в реактивный .NET
 
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
 
Машинное обучение на платформе .NET
Машинное обучение на платформе .NETМашинное обучение на платформе .NET
Машинное обучение на платформе .NET
 

Recently uploaded (9)

CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
 
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdfMalware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
 
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
 
Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
 
Ransomware_Q3 2023. The report [RU].pdf
Ransomware_Q3 2023.  The report [RU].pdfRansomware_Q3 2023.  The report [RU].pdf
Ransomware_Q3 2023. The report [RU].pdf
 
MS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdfMS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdf
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
 

Многопоточное программирование на C#, путевые заметки

  • 1. Многопоточное программирование на C#, путевые заметки Дмитрий Литичевский ByndyuSoft 11-я конференция .NET разработчиков 31 октября 2015 dotnetconf.ru
  • 2. 2 О себе  Team lead в компании ByndyuSoft  Аспирант ЧелГУ, дискретная математика и математическая кибернетика  Любитель вселенной Warhammer 40000 В МРАЧНОЙ ТЬМЕ ДАЛЁКОГО БУДУЩЕГО ЕСТЬ ТОЛЬКО ВОЙНА...
  • 3. 3 Прежде чем начать Зачем нам все это? Хотим эффективно использовать имеющиеся ресурсы. Когда это сработает? Обрабатывается поток ресурсоемких слабосвязанных друг с другом задач
  • 4. 4 Асинхронная обработка Одним из способов ускорить приложения является асинхронный запуск длительных операций, мы запускаем ее и не ждем завершения Возможные примеры: 1. Cетевые запросы; 2. Доступ к диску; 3. Сложные вычисления. l Основное различие заключается в том, в каком потоке выполняется запущенная длительная операция.
  • 5. 5 Что предлагает нам C# Event-based Asynchronous Pattern (EAP) private void DownloadContentFromUrl(Uri uri) { var client = new WebClient(); client.DownloadStringCompleted += OnDownloadStringCompleted; client.DownloadStringAsync(uri); } Интерфейс IAsyncResult private void LookupHostName() { Dns.BeginGetHostAddresses("dotnetconf.ru", OnNameResolved, null); } private void OnNameResolved(IAsyncResult ar) { var addresses = Dns.EndGetHostAddresses(ar); } Task-based Asynchronous Pattern (TAP)
  • 6. 6 Договор с TAP Не допустимы ref и out параметры методов. Метод должен возвращать значение типа Task<T>, Task или void в зависимости от возвращаемого значения синхронного метода. Исключение из-за ошибки в параметрах вызова метода можно возбуждать непосредственно (используя оператор throw), остальные исключения следует помещать в объект Task. Единый API для работы с асинхронными операциями, что позволяет реализовать на уровне компилятора такие средства как async/await.
  • 7. 7 Примеры использования TAP var x = await Task.Run(() => SolveSystem(a, b)); Task t = Task.Factory.StartNew(() => SolveSystem(a, b), cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current); private async Task DownloadPageAsync(string uri) { using (var client = new HttpClient()) using (var response = await client.GetAsync(uri)) using (var content = response.Content) { var result = await content.ReadAsStringAsync(); // Processing } }
  • 8. 8 TAP, обработка ошибок Методы возвращают Task илиTask<T>, ожидаем простой таск используя await. try { var pageContent = await webClient.DownloadStringTaskAsync(uri); // Processing } catch (Exception ex) { // Handling } Исключение возбуждается там, где находится оператор await, перехватывается, все красиво и здорово.
  • 9. 9 TAP, обработка ошибок Методы возвращают Task илиTask<T>, ожидаем результат используя методы Wait, WaitAll, WaitAny try { var task = webClient.DownloadStringTaskAsync(uri); task.Wait(); // Processing } catch (AggregateException ex) { foreach (var inner in ex.InnerExceptions) {/*Handling*/ } } AggregateException возбуждается в месте вызова Wait, WaitAll, WaitAny, возникшие исключения находятся в свойстве InnerExceptions.
  • 10. 10 TAP, обработка ошибок Методы оформлены по стандарту, ожидаем составной таск var allTask = Task.WhenAll(tasks); try { await allTask; } catch { foreach (var ex in allTask.Exception.InnerExceptions) { // Handling } } При выполнении тасков может возникать несколько исключений, но в операторе await возбуждается одно из них. Все исключения могут быть найдены в коллекции InnerExceptions объекта класса AggregateException, лежащего в свойстве Exception ожидаемого таска.
  • 11. 11 TAP, обработка ошибок Асинхронный метод возвращает Task или void, мы не хотим или не можем дождаться его завершения. Тогда мы можем: 1. Реализовать обработку ошибок внутри самой операции; 2. Если метод все же возвращает таск, то добавить к нему Continuation var task = DownloadPageAsync("http://dotnetconf.ru/"); task.ContinueWith(t => t.Exception.Handle(e => { // Handling return true; }), TaskContinuationOptions.OnlyOnFaulted); private async Task DownloadPageAsync(string uri) { using (var webclient = new WebClient()) { var content = await webclient.DownloadStringTaskAsync(uri); // Processing } }
  • 12. 12 TAP, отмена операции Используется классы CancellationToken и CancellationTokenSource Способы прерывания: 1. По прошествии определенного времени с помощью CancelAfter 2. В ручную с помощью Cancell using (var cts = new CancellationTokenSource()) { cts.CancelAfter(TimeSpan.FromMilliseconds(100)); try { var task = DownloadPageAsync("http://dotnetconf.ru/", cts.Token); task.Wait(cts.Token); } catch (OperationCanceledException) { // Handling } catch (AggregateException) { // Handling } }
  • 13. 13 TAP, отмена операции Обработка сводится к периодической проверке вызываемым кодом свойства IsCancellationRequested и вызову метода ThrowIfCancellationRequested объекта CancellationToken. Task.Run(() => { for (var i = 0; i < n; i++) { // Calculations token.ThrowIfCancellationRequested(); } }, token) .Wait(); Если требуется освобождение ресурсов, то мы можем периодически проверять флаг IsCancellationRequested.
  • 14. 14 Типы многопоточная обработки Организацию многопоточной обработки данных в приложениях можно разделить на два типа: 1. Задачи заранее известны, организовывать их обработку будем с использованием библиотек TPL или PLINQ. 2. Задачи генерируются в процессе обработки, модель producer and consumer будем реализовывать при помощи класса ThreadPool или библиотеки Rx. Данная классификация является условной призвана помочь автору структурировать остальную часть доклада.
  • 15. 15 TPL, теория TPL содержит класс Parallel, возможности которого аналогичны библиоке OpenMP для С++. Для распараллеливания циклов в классе объявлены три перегруженных метода: 1. For, организует распаралеленный цикл for, в качестве одного из аргументов передается тело цикла. 2. ForEach, организует распаралеленную обработку коллекций, реализующих интерефейс IEnumerable<T>, в качестве одного из аргументов передается тело цикла. 3. Invoke, организует параллельный вызов экземпляров Action, переданных в качестве параметров. Ошибки, возникшие и не перехваченные в обрабатывающих потоках, помещаются в экземпляр AggregateException. Вызвавший методы поток блокируется до завершения обработки.
  • 16. 16 TPL, примеры Parallel.ForEach(orders, new ParallelOptions {MaxDegreeOfParallelism = threadsCount}, UpdateOrder); Parallel.Invoke( () => DeleteSubjects(orderId), () => DeleteDocuments(orderId), () => DeleteSuppliers(orderId) );
  • 17. 17 TPL, нюансы Использование экземпляра ParallelOptions позволяет более полно контролировать выполняемые операции: 1. MaxDegreeOfParallelism, регулирует количество потоков, которые будут использованы для обработки. 2. CancellationToken, токен, используемый для отмены запускаемой операции. 3. TaskScheduler, управляет запуском потоков обработки задач. Использование класса Partitioner позволяет управлять разбиением задач между потоками и их балансировкой. TPL может динамически распределять нагрузку между потоками или же может распределить их некоторым образом перед стартом выполнения расчетов и не менять по ходу обработки, это настраивается с помощью Partitioner.Create. var tasks = Enumerable.Range(1, 100).ToArray(); Parallel.ForEach(Partitioner.Create(tasks, true), ProcessItem);
  • 18. 18 PLINQ, теория PLINQ является реализацией LINQ, распеределенно выполняющей запросы. Для этого были добавлены классы ParallelEnumerable, ParallelQuery, ParallelQuery<T>, а также нескольких других. Не все операторы LINQ реализованы в PLINQ. Этапы выполнения запроса: 1. Выбор модели выполнения (параллельно или последовательно), будем считать, что запрос будет выполняться параллельно. 2. Распределение задач между потоками. 3. Запуск выполнения запроса; 4. Слияние результатов работы отдельных потоков в вызывающем потоке; 5. Итерация по результатам запроса. Ошибки, возникшие и не перехваченные в обрабатывающих потоках, помещаются в экземпляр AggregateException.
  • 19. 19 PLINQ, пример var tradeItemsForUpdate = tradeItems .AsParallel() .WithDegreeOfParallelism(_threadsCount) .Where(UpdateNeeded) .ToArray(); var range = Enumerable.Range(0, 100000000).ToArray(); var partitioner = Partitioner.Create(range, true); var query = partitioner.AsParallel().Select(Calc); Для написания запросов с использованием PLINQ достаточно вызвать метод разширения ParallelEnumerable.AsParallel после чего запрос будет строиться с использованием методов PLINQ.
  • 20. 20 PLINQ, нюансы В случае 100% уверенности в том, что распараллеливание запроса принесет прирост в скорости, можно заставить среду исполнять его параллельно, вызвав метода WithExecutionMode, вызванного c параметром ParallelExecutionMode.ForceParallelism. var ordersForUpdate = orders.AsParallel() .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .Where(UpdateNeeded) .ToArray(); Разбиение задач между потоками настраивается. Для этого используется уже описанный ранее класс Partitioner и его метод Create. С его помощью можно включить динамическую балансировку задач, отключенную по умолчанию для массивов и коллекций, реализующих Ilist. Если описанного недостаточно, то можно реализовать свой Partitioner согласно требованиям TPL.
  • 21. 21 PLINQ, нюансы В отличии от первых двух пунктов цепи выполнения запроса, существует гораздо больше возможностей влияния на его выполнение. Допустимо следующее: 1. Управлять числом обрабатывающих потоков с помощью метода WithDegreeOfParallelism. 2. Управлять досрочным прекращением операций с помощью метода WithCancellation, передав в качестве параметра экземпляр CancellationToken. 3. Управлять учетом порядка записей исходной коллекции при генерации результатов с помощью методов AsOrdered/AsUnordered. var ordersForUpdate = orders.AsParallel() .AsOrdered() .WithDegreeOfParallelism(threadsCount) .WithCancellation(cts.Token) .Where(UpdateNeeded) .ToArray();
  • 22. 22 PLINQ, нюансы Для обработки результатов запросов из примеров необходимо слить вместе результаты отдельных потоков и отдать их вызвавшему. Это настраивается при помощи метода WithMergeOptions, доступны следующие варианты: 1. FullyBuffered, результаты полностью буферизуются. 2. AutoBuffered, результаты частично буферизуются. 3. NotBuffered, результаты не буферизуются. var ordersForUpdate = orders.AsParallel() .WithMergeOptions(ParallelMergeOptions.FullyBuffered) .Where(UpdateNeeded); foreach (var order in ordersForUpdate) UpdateOrder(order);
  • 23. 23 PLINQ, нюансы Если обработка результатов запроса может быть выполнена параллельно и ее порядок не важен, то можно воспользоваться методом ForAll, передав в него тело цикла, сэкономив на слиянии промежуточных результатов. orders.AsParallel() .ForAll(x => { if(UpdateNeeded(x)) UpdateOrder(x); });
  • 24. 24 Использование ThreadPool Простейший вариант параллельной обработки — это использование метода QueueUserWorkItem класса ThreadPool. while (true) { var message = GetMessage(queueName); if (message != null) ThreadPool.QueueUserWorkItem(DispatchMessage, message); else Thread.Sleep(30000); }
  • 25. 25 Использование ThreadPool Для ограничения числа отправляемых в ThreadPool задач, например, при чтении из очереди, можно использовать Semaphore. _semaphore.WaitOne(); ThreadPool.QueueUserWorkItem(DispatchMessage, message); private void DispatchMessage(object state) { var message = (MessageInfo)state; try { OnMessageReceive(this, message); } finally { _semaphore.Release(); } }
  • 26. 26 Использование Rx Состоит из интерфейсов Iobservable<T> и IObserver<T>, включенных в .NET начиная с версии 4 и nuget пакета Rx-Main. public interface IObservable<T> { IDisposable Subscribe(IObserver<T> observer); } public interface IObserver<T> { void OnNext(T value); void OnCompleted(); void OnException(Exception error); } Rx предлагает другую модель обработки данных, push вместо pull, о новых событиях нас будет уведомлять сама библиотека.
  • 27. 27 Использование Rx Библиотека позволяет настраивать, в каких потоках будут выполняться методы Observer'а. Для этих целей служат методы SubscribeOn и ObserveOn класса Observable. _customerService.GetCustomers() .SubscribeOn(Scheduler.TaskPool) .Subscribe(Customers.Add); Метод ObserveOn определяет какой Scheduler'е будет использоваться для вызовов методов Observer'а. Метод SubscribeOn определяет где будет порождаться и обрабатываться уведомления для Observer'ов. Интересны следующие Scheduler'ы: 1. Scheduler.NewThread, обработка будет запущена в отдельном потоке. 2. Scheduler.ThreadPool, обработка будет запущена в ThreadPool. 3. Scheduler.TaskPool, обработка будет запущена в TaskPool.
  • 28. 28 Литература и примеры Литература: 1. https://msdn.microsoft.com/ru-ru/library/dd997415(v=vs.110).aspx 2. https://msdn.microsoft.com/ru-ru/library/hh524395.aspx 3. https://msdn.microsoft.com/en-us/library/jj155759.aspx 4. http://habrahabr.ru/post/168669/ 5. https://msdn.microsoft.com/en-us/library/dd997425(v=vs.110).aspx 6. https://msdn.microsoft.com/en-us/library/dd997411.aspx 7. http://stackoverflow.com/questions/15773008/reactive-framework-as- message-queue-using-blockingcollection 8. http://www.introtorx.com/content/v1.0.10621.0/15_SchedulingAndThreading.ht ml 9. Асинхронное программирование в C# 5.0, Алекс Дэвис 10. Concurrency in C# Cookbook, Stephen Cleary 11. C# in depth, Jon Skeet Примеры: github
  • 29. 29 Спасибо за внимание Литичевский Дмитрий ByndyuSoft dmitry.litichevskiy@byndyusoft.com vk