Модель приложений .NET. Потоки.
Метод Thread::Sleep (Поток::Режим ожидания) приводит к приостановке выполнения текущего потока на указанный период времени. Вызов Thread::Suspend (Поток::Приостановить) блокирует выполнение потока до вызова Thread::Resume (Поток::Продолжить) другим потоком. Поток также может быть заблокирован, если он ожидает завершения другого потока (Thread::Join (Поток::Объединить)). Этот метод использовался в примерах Threading (Организация поточной обработки) так, чтобы главный поток мог ждать завершения выполнения запросов резервирования. Поток может также блокироваться при ожидании синхронизирующего замка (в критической секции).
Вызов Thread::Interrupt (Поток::Прерывание) для заблокированного потока приводит к его пробуждению. Поток получит ThreadlnterruptedException. И если он не перехватывает это исключение, то среда времени выполнения это исключение перехватит и уничтожит поток.
Если, в качестве последней надежды, нужно уничтожить поток напрямую, необходимо для этого потока сделать вызов метода Thread::Abort (Поток:прекратить). Метод Thread::Abort (Поток::Прекратить) приводит к запуску исключения Thread-AbortException. Это исключение не может быть перехвачено, но оно приведет к выполнению всех блоков finally (наконец). Кроме того, Thread::Abort (Поток:: Прекратить) не приводит к пробуждению ожидающего потока.
Поскольку для выполнения блоков finally (наконец) может потребоваться время, или потоки могут находиться в состоянии ожидания, то потоки, выполнение которых прекращается, могут быть завершены не сразу. Поэтому, если нужно убедиться в том, что выполнение потока завершено, необходимо ожидать завершения потока, вызвав метод Thread::Join (Поток::Объединить).
Классы синхронизации
Каркас .NET Framework содержит классы, представляющие собой стандартные в Win32 объекты синхронизации. Все эти классы являются производными от абстрактного класса WaitHandle. Этот класс имеет статические методы Wait All и WaitAny, которые позволяют ожидать сигнал от нескольких (или только от одного) объектов синхронизации. Он также содержит метод экземпляра WaitOne, который позволяет ожидать сигнал отданного экземпляра. Способ приема сигнала объектом зависит от конкретного типа объекта синхронизации, который является производным от WaitHandle.
Объект Mutex (Взаимное исключение) используется для синхронизации процессов. Мониторы и критические секции работают только в пределах одного процесса. AutoResetEvent и ManualResetEvent используются для того, чтобы просигнализировать, произошло ли какое-нибудь событие. AutoResetEvent остается в сигнальном состоянии, пока ожидающий поток не будет освобожден. ManualResetEvent остается в сигнальном состоянии, пока его состояние не установлено в несигнальное с помощью метода Reset (Сброс). Следовательно, много потоков могут получить сигнал с помощью такого события. В отличие от использования мониторов, код не должен ожидать сигнала прежде, чем устанавливается сигнал сброса события, которое посылает сигнал потоку.
Каркас предоставляет классы для разрешения некоторых стандартных задач организации поточной обработки. Методы класса Interlocked (Сблокированный) разрешают атомарные операции с совместно используемыми значениями. Это операции типа приращения, декремента, сравнения и обмена. ReaderWriterLock используется, чтобы предоставить доступ для одиночной записи и множественного чтения структур данных. Класс ThreadPool позволяет управлять пулом рабочих потоков.
Автоматическая синхронизация
Атрибуты можно использовать для синхронизации доступа к методам экземпляра (нестатическим) и нестатическим полям класса. Доступ к статическим полям и методам не синхронизируется. Чтобы использовать эту возможность нужно создать класс, производный от класса System::ContextBoundObject и применить к нему атрибут Synchronization (Синхронизация). Этот атрибут не применяется к отдельному полю или методу.
Данный атрибут находится в пространстве имен System::Runtime::Remoting:: Contexts (Система::Время выполнения:: Remoting::Контексты). Он описывает синхронизационные требования для экземпляра класса, к которому применяется. В конструктор SynchronizationAttribute можно передать одно из четырех значений, являющихся статическими полями класса SynchronizationAttribute: NONSUPPORTED, SUPPORTED (ПОДДЕРЖИВАЕМЫЙ), REQUIRED (ТРЕБУЕМЫЙ), REQUIRES_NEW. Пример Threading (Организация поточной обработки) на шаге 3 иллюстрирует, как это сделать.
using namespace System:: Runtime:: Remoting:: Contexts; // использование пространства имен // Система:: Время выполнения:: Remoting:: Контексты; // SynchronizationAttribute:: REQUIRED (ТРЕБУЕМЫЙ) – 4 [Synchronization(4) ] // [Синхронизация (4)] public _gc _abstract class Broker: // сборщик мусора – абстрактный класс Broker: public ContextBoundObject { };