Working with .NET Threads

48
Работа с потоками в .NET

description

Презентация к докладу - работа с потоками в .net * Основе работы с потоками * Средства блокирующей синхронизации * Неблокирующая синхронизация * Асинхронная модель программирования * Пул потоков * Класс BackGroundWorker * Задачи * Модель поставщик-потребитель * Блокировка с двойной проверкой

Transcript of Working with .NET Threads

Page 1: Working with .NET Threads

Работа с потоками в .NET

Page 2: Working with .NET Threads

О чем сегодня поговорим

Основные работы с потоками Средства блокирующей синхронизации Неблокирующая синхронизация Асинхронная модель

программирования Пул потоков Класс BackGroundWorker Задачи Модель поставщик-потребитель Блокировка с двойной проверкой

Page 3: Working with .NET Threads

Определение потока выполнения

Пото�к выполне�ния (англ. thread — нить) — наименьшая единица обработки, исполнение которой может быть назначено ядром операционной системы

Page 4: Working with .NET Threads

Плюсы многопоточного приложения

Параллельная обработка запросов Взаимодействие по сети или с БД Выполнение операций, занимающих

много времени Разделение задач по приоритетам Сохранение возможности работы с UI

при обработке других задач

Page 5: Working with .NET Threads

Недостатки многопоточного приложения

Увеличенный расход памяти Захват времени процессора – если в

одном процессе находится большое количество потоков, то потоки другого процесса срабатывают реже

Контроль доступа к разделяемым ресурсам

Отслеживание времени жизни потока

Page 6: Working with .NET Threads

Отличие потоков от процессов

Процессы - независимы, тогда как потоки выполнения существуют как составные элементы процессов

Процессы несут значительно больше информации о состоянии

Процессы имеют отдельные адресные пространства, тогда как потоки выполнения совместно используют их адресное пространство

Процессы взаимодействуют только через предоставляемые системой механизмы связей между процессами

Переключение контекста между потоками выполнения в одном процессе, как правило, быстрее, чем переключение контекста между процессами.

Page 7: Working with .NET Threads

Класс Thread

Page 8: Working with .NET Threads

Класс Thread

Page 9: Working with .NET Threads

Приоритет потока

Page 10: Working with .NET Threads

Ожидание завершения потока

Page 11: Working with .NET Threads

Фоновые потоки

Page 12: Working with .NET Threads

Обработка исключений в потоках

Page 13: Working with .NET Threads

Перехват необработанных исключений

Page 14: Working with .NET Threads

Останов потока

 Thread.InterruptThread.Abort

Page 15: Working with .NET Threads

Thread.Interrupt

Если Interrupt вызывается для неблокированного потока, поток продолжает исполнение до точки следующей блокировки, в которой и генерируется исключениеThreadInterruptedException.

Page 16: Working with .NET Threads

Thread.Abort

• После вызова метода Thread.Abort из другого потока, в целевом потоке генерируется исключение ThreadAbortException, которое по своей природе является асинхронным, а это значит, что оно может возникнуть практически в любой точке управляемого кода

• ThreadAbortException не может возникнуть внутри статического конструктора, внутри блоков catch/finally, внутри constrained execution region или внутри неуправляемого кода.

Page 17: Working with .NET Threads

Thread.Abort

Page 18: Working with .NET Threads

Состояния потока

Page 19: Working with .NET Threads

Когда (не)использовать потоки?

Page 20: Working with .NET Threads

Средства блокирующей синхронизации

Класс Monitor и конструкция lock()

ReaderWriterLockSlimMutexSemaphoreWaitHandle

Page 21: Working with .NET Threads

Класс Monitor

Класс Monitor контролирует доступ к объектам, предоставляя блокировку объекта одному потоку. Блокировки объектов предоставляют возможность ограничения доступа к части кода, обычно называемой критической секцией. Пока поток владеет блокировкой для объекта, никакой другой поток не может ею завладеть.

Page 22: Working with .NET Threads

Класс Monitor

Класс Monitor контролирует доступ к объектам, предоставляя блокировку объекта одному потоку. Блокировки объектов предоставляют возможность ограничения доступа к части кода, обычно называемой критической секцией. Пока поток владеет блокировкой для объекта, никакой другой поток не может ею завладеть.

Page 23: Working with .NET Threads

Double-check locking

Page 24: Working with .NET Threads

Класс ReaderWriterLockSlim

Представляет блокировку, используемую для управления доступом к ресурсу, которая позволяет нескольким потокам производить считывание или получать монопольный доступ на запись.

Page 25: Working with .NET Threads

Mutex

Примитив синхронизации, который также может использоваться в межпроцессорной синхронизации

Page 26: Working with .NET Threads

Semaphore

Ограничивает число потоков, которые могут одновременно получать доступ к ресурсу или пулу ресурсов.

Page 27: Working with .NET Threads

WaitHandle

AutoResetEvent ManualResetEvent 

Page 28: Working with .NET Threads

AutoResetEvent Уведомляет ожидающий поток о том, что произошло событие. AutoResetEvent позволяет потокам взаимодействовать друг с

другом путем передачи сигналов. Как правило, этот класс используется, когда потокам требуется исключительный доступ к ресурсу.

Поток ожидает сигнала, вызывая метод WaitOne при возникновении AutoResetEvent. Если AutoResetEvent находится в несигнальном состоянии, поток будет заблокирован, ожидая сигнала потока, в настоящий момент контролирующего ресурс, о том, что ресурс доступен (для этого вызывается метод Set).

Вызов Set сигнализирует событию AutoResetEvent о необходимости освобождения ожидающего потока. Событие AutoResetEventостается в сигнальном состоянии до освобождения одного ожидающего потока, а затем возвращается в несигнальное состояние. Если нет ожидающих потоков, состояние остается сигнальным бесконечно.

Если поток вызывает метод WaitOne, а AutoResetEvent находится в сигнальном состоянии, поток не блокируется. AutoResetEventнемедленно освобождает поток и возвращается в несигнальное состояние.

Page 29: Working with .NET Threads

AutoResetEvent

AutoResetEvent очень похож на турникет – один билет позволяет пройти одному человеку. Приставка “auto” в названии относится к тому факту, что открытый турникет автоматически закрывается или “сбрасывается” после того, как позволяет кому-нибудь пройти. Поток блокируется у турникета вызовом WaitOne (ждать (wait) у данного (one) турникета, пока он не откроется), а билет вставляется вызовом метода Set. Если несколько потоков вызываютWaitOne, за турникетом образуется очередь. Билет может “вставить” любой поток – другими словами, любой (неблокированный) поток, имеющий доступ к объекту AutoResetEvent, может вызвать Set, чтобы пропустить один блокированный поток.

Page 30: Working with .NET Threads

AutoResetEvent Конструктор EventWaitHandle также позволяет создавать

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

Page 31: Working with .NET Threads

AutoResetEvent

Page 32: Working with .NET Threads

AutoResetEvent

Page 33: Working with .NET Threads

ManualResetEvent

ManualResetEvent – это разновидность AutoResetEvent. Отличие состоит в том, что он не сбрасывается автоматически, после того как поток проходит через WaitOne, и действует как шлагбаум – Set открывает его, позволяя пройти любому количеству потоков, вызвавших WaitOne. Resetзакрывает шлагбаум, потенциально накапливая очередь ожидающих следующего открытия.

Эту функциональность можно эмулировать при помощи булевой переменной "gateOpen" (объявленной как volatile) в комбинации со "spin-sleeping" – повторением проверок флага и ожидания в течении короткого промежутка времени.

ManualResetEvent может использоваться для сигнализации о завершении какой-либо операции или инициализации потока и готовности к выполнению работы.

Page 34: Working with .NET Threads

Неблокирующая синхронизация

Page 35: Working with .NET Threads

Неблокирующая синхронизация

Page 36: Working with .NET Threads

Асинхронная модель программирования

Page 37: Working with .NET Threads

Асинхронная модель программирования

Page 38: Working with .NET Threads

Пул потоков

Page 39: Working with .NET Threads

Пул потоков

Предоставляет пул потоков, который может использоваться для выполнения задач, отправки рабочих элементов, обработки асинхронного ввода-вывода, ожидания от имени других потоков и обработки таймеров.

Page 40: Working with .NET Threads

Клаcc BackgroundWorker Асинхронное выполнение метода Возможна отмена выполнения Сигнализация хода выполнения

Page 41: Working with .NET Threads

Клаcc BackgroundWorker

Page 42: Working with .NET Threads

Клаcc BackgroundWorker

Page 43: Working with .NET Threads

Клаcc BackgroundWorker

Page 44: Working with .NET Threads

Task и Task<T>

Page 45: Working with .NET Threads

Task и Task<T>

Page 46: Working with .NET Threads

Какие темы не затронули

Класс ParallelPLINQ.NET 4.5 и async

Page 47: Working with .NET Threads

О чем сегодня поговорилиОсновные понятия работы с

потокамиСредства

блокирующей синхронизацииНеблокирующая синхронизацияАсинхронная модель

программированияПул потоковКласс BackGroundWorkerЗадачи

Page 48: Working with .NET Threads

Контакты

Трёшников Павел Ведущий разработчик СМС-ИТ

▪ www.sms-automation.ru

e-mail: [email protected] twitter: @treshnikov