WaitHandle Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Инкапсулирует связанные с операционной системой объекты, ожидающие монопольного доступа к общим ресурсам.
public ref class WaitHandle abstract : IDisposable
public ref class WaitHandle abstract : MarshalByRefObject, IDisposable
public abstract class WaitHandle : IDisposable
public abstract class WaitHandle : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable
type WaitHandle = class
interface IDisposable
type WaitHandle = class
inherit MarshalByRefObject
interface IDisposable
[<System.Runtime.InteropServices.ComVisible(true)>]
type WaitHandle = class
inherit MarshalByRefObject
interface IDisposable
Public MustInherit Class WaitHandle
Implements IDisposable
Public MustInherit Class WaitHandle
Inherits MarshalByRefObject
Implements IDisposable
- Наследование
-
WaitHandle
- Наследование
- Производный
- Атрибуты
- Реализации
Примеры
В следующем примере кода показано, как два потока могут выполнять фоновые задачи, пока основной поток ожидает завершения задач с помощью статических WaitAnyWaitHandle методов и WaitAll класса .
using namespace System;
using namespace System::Threading;
public ref class WaitHandleExample
{
// Define a random number generator for testing.
private:
static Random^ random = gcnew Random();
public:
static void DoTask(Object^ state)
{
AutoResetEvent^ autoReset = (AutoResetEvent^) state;
int time = 1000 * random->Next(2, 10);
Console::WriteLine("Performing a task for {0} milliseconds.", time);
Thread::Sleep(time);
autoReset->Set();
}
};
int main()
{
// Define an array with two AutoResetEvent WaitHandles.
array<WaitHandle^>^ handles = gcnew array<WaitHandle^> {
gcnew AutoResetEvent(false), gcnew AutoResetEvent(false)};
// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime timeInstance = DateTime::Now;
Console::WriteLine("Main thread is waiting for BOTH tasks to " +
"complete.");
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
WaitHandle::WaitAll(handles);
// The time shown below should match the longest task.
Console::WriteLine("Both tasks are completed (time waited={0})",
(DateTime::Now - timeInstance).TotalMilliseconds);
// Queue up two tasks on two different threads;
// wait until any tasks are completed.
timeInstance = DateTime::Now;
Console::WriteLine();
Console::WriteLine("The main thread is waiting for either task to " +
"complete.");
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
int index = WaitHandle::WaitAny(handles);
// The time shown below should match the shortest task.
Console::WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime::Now - timeInstance).TotalMilliseconds);
}
// This code produces the following sample output.
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
using System;
using System.Threading;
public sealed class App
{
// Define an array with two AutoResetEvent WaitHandles.
static WaitHandle[] waitHandles = new WaitHandle[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
// Define a random number generator for testing.
static Random r = new Random();
static void Main()
{
// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime dt = DateTime.Now;
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
// The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})",
(DateTime.Now - dt).TotalMilliseconds);
// Queue up two tasks on two different threads;
// wait until any task is completed.
dt = DateTime.Now;
Console.WriteLine();
Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles);
// The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime.Now - dt).TotalMilliseconds);
}
static void DoTask(Object state)
{
AutoResetEvent are = (AutoResetEvent) state;
int time = 1000 * r.Next(2, 10);
Console.WriteLine("Performing a task for {0} milliseconds.", time);
Thread.Sleep(time);
are.Set();
}
}
// This code produces output similar to the following:
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
//
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
Imports System.Threading
NotInheritable Public Class App
' Define an array with two AutoResetEvent WaitHandles.
Private Shared waitHandles() As WaitHandle = _
{New AutoResetEvent(False), New AutoResetEvent(False)}
' Define a random number generator for testing.
Private Shared r As New Random()
<MTAThreadAttribute> _
Public Shared Sub Main()
' Queue two tasks on two different threads;
' wait until all tasks are completed.
Dim dt As DateTime = DateTime.Now
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
WaitHandle.WaitAll(waitHandles)
' The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})", _
(DateTime.Now - dt).TotalMilliseconds)
' Queue up two tasks on two different threads;
' wait until any tasks are completed.
dt = DateTime.Now
Console.WriteLine()
Console.WriteLine("The main thread is waiting for either task to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
Dim index As Integer = WaitHandle.WaitAny(waitHandles)
' The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).", _
index + 1,(DateTime.Now - dt).TotalMilliseconds)
End Sub
Shared Sub DoTask(ByVal state As [Object])
Dim are As AutoResetEvent = CType(state, AutoResetEvent)
Dim time As Integer = 1000 * r.Next(2, 10)
Console.WriteLine("Performing a task for {0} milliseconds.", time)
Thread.Sleep(time)
are.Set()
End Sub
End Class
' This code produces output similar to the following:
'
' Main thread is waiting for BOTH tasks to complete.
' Performing a task for 7000 milliseconds.
' Performing a task for 4000 milliseconds.
' Both tasks are completed (time waited=7064.8052)
'
' The main thread is waiting for either task to complete.
' Performing a task for 2000 milliseconds.
' Performing a task for 2000 milliseconds.
' Task 1 finished first (time waited=2000.6528).
Комментарии
Класс WaitHandle инкапсулирует собственный дескриптор синхронизации операционной системы и используется для представления всех объектов синхронизации в среде выполнения, допускающих несколько операций ожидания. Сравнение дескрипторов ожидания с другими объектами синхронизации см. в статье Общие сведения о примитивах синхронизации.
Сам WaitHandle класс является абстрактным. Классы, производные от WaitHandle , определяют механизм сигнализации, указывающий на получение или освобождение доступа к общему ресурсу, но они используют унаследованные WaitHandle методы для блокировки во время ожидания доступа к общим ресурсам. Классы, производные от :WaitHandle
Класс EventWaitHandle и его производные классы и ManualResetEventAutoResetEvent .
Класс Semaphore. См . раздел Семафор и СемафорSlim.
Потоки могут блокировать отдельный дескриптор ожидания, вызывая метод WaitOneэкземпляра , который наследуется классами, производными от WaitHandle.
Производные классы WaitHandle отличаются сходством потоков. Дескриптор ожидания событий (EventWaitHandle, AutoResetEventи ManualResetEvent) и семафоры не имеют сходства потоков; любой поток может сообщить об дескрипторе ожидания события или семафоре. Мьютексы, с другой стороны, имеют сходство потоков; Поток, владеющий мьютексом, должен освободить его, и если поток вызывает ReleaseMutex метод для мьютекса, которым он не владеет.
WaitHandle Так как класс является производным от MarshalByRefObject, эти классы можно использовать для синхронизации действий потоков через границы домена приложения.
В дополнение к производным классам WaitHandle класс имеет ряд статических методов, которые блокируют поток до тех пор, пока один или несколько объектов синхронизации не получат сигнал. Сюда входит следующее.
SignalAndWait, который позволяет потоку сигнализировать один дескриптор ожидания и немедленно ожидать другого.
WaitAll, который позволяет потоку ждать, пока все дескрипторы ожидания в массиве не получат сигнал.
WaitAny, который позволяет потоку ждать, пока не будет показано любое из указанного набора дескрипторов ожидания.
Перегрузки этих методов предоставляют интервалы времени ожидания для отказа от ожидания и возможность выйти из контекста синхронизации перед вводом ожидания, позволяя другим потокам использовать контекст синхронизации.
Важно!
Этот тип реализует интерфейс IDisposable. Завершив использование типа или производного от него типа, его следует удалить прямо или косвенно. Чтобы сделать это прямо, вызовите его метод Close в блоке try
/catch
. Чтобы сделать это косвенно, используйте языковые конструкции, такие как using
(в C#) или Using
(в Visual Basic). Дополнительные сведения см. в разделе "Использование объекта, реализующего IDisposable" в статье об интерфейсе IDisposable.
WaitHandle Dispose реализует шаблон . См. раздел Реализация метода Dispose. При наследоваве от WaitHandle, используйте свойство для хранения собственного дескриптора SafeWaitHandle операционной системы. Не нужно переопределять защищенный Dispose метод, если не используются дополнительные неуправляемые ресурсы.
Конструкторы
WaitHandle() |
Инициализирует новый экземпляр класса WaitHandle. |
Поля
InvalidHandle |
Представляет недопустимый собственный дескриптор операционной системы. Это поле доступно только для чтения. |
WaitTimeout |
Указывает, что время ожидания операции WaitAny(WaitHandle[], Int32, Boolean) истекло до получения сигнала каким-либо из дескрипторов ожидания. Это поле является константой. |
Свойства
Handle |
Устаревшие..
Устаревшие..
Возвращает или задает собственный дескриптор операционной системы. |
SafeWaitHandle |
Возвращает или задает собственный дескриптор операционной системы. |
Методы
Close() |
Освобождает все ресурсы, удерживаемые текущим объектом WaitHandle. |
CreateObjRef(Type) |
Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом. (Унаследовано от MarshalByRefObject) |
Dispose() |
Освобождает все ресурсы, используемые текущим экземпляром класса WaitHandle. |
Dispose(Boolean) |
При переопределении в производном классе освобождает неуправляемые ресурсы, используемые объектом WaitHandle, и при необходимости освобождает управляемые ресурсы. |
Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
Finalize() |
Освобождает ресурсы, удерживаемые текущим экземпляром. |
GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
GetLifetimeService() |
Устаревшие..
Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра. (Унаследовано от MarshalByRefObject) |
GetType() |
Возвращает объект Type для текущего экземпляра. (Унаследовано от Object) |
InitializeLifetimeService() |
Устаревшие..
Получает объект службы времени существования для управления политикой времени существования для этого экземпляра. (Унаследовано от MarshalByRefObject) |
MemberwiseClone() |
Создает неполную копию текущего объекта Object. (Унаследовано от Object) |
MemberwiseClone(Boolean) |
Создает неполную копию текущего объекта MarshalByRefObject. (Унаследовано от MarshalByRefObject) |
SignalAndWait(WaitHandle, WaitHandle) |
Подает сигнал одному объекту WaitHandle и ожидает другого. |
SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean) |
Передает сигнал одному объекту WaitHandle и ожидает сигнализации другого, задавая время ожидания в виде 32-разрядного целого числа со знаком и указывая, следует ли выйти из домена синхронизации контекста до начала ожидания. |
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean) |
Передает сигнал одному объекту WaitHandle и ожидает сигнализации другого, задавая время ожидания в виде TimeSpan и указывая, следует ли выйти из домена синхронизации контекста до начала ожидания. |
ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
WaitAll(WaitHandle[]) |
Ожидает получения сигнала всеми элементами заданного массива. |
WaitAll(WaitHandle[], Int32) |
Ожидает получения сигнала всеми элементами заданного массива, используя значение Int32 для указания интервала времени. |
WaitAll(WaitHandle[], Int32, Boolean) |
Ожидает получения сигнала всеми элементами заданного массива, используя значение типа Int32 для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitAll(WaitHandle[], TimeSpan) |
Ожидает получения сигнала всеми элементами заданного массива, используя значение TimeSpan для указания интервала времени. |
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Ожидает получения сигнала всеми элементами заданного массива, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitAny(WaitHandle[]) |
Ожидает получения сигнала какими-либо элементами заданного массива. |
WaitAny(WaitHandle[], Int32) |
Ожидает получения сигнала любыми элементами указанного массива, используя 32-разрядное целое число со знаком для задания интервала времени. |
WaitAny(WaitHandle[], Int32, Boolean) |
Ожидает, пока какой-либо из элементов заданного массива не получит сигнал, используя 32-разрядное целое число со знаком для задания интервала времени и определения, нужно ли осуществить выход из домена синхронизации до окончания ожидания. |
WaitAny(WaitHandle[], TimeSpan) |
Ожидает получения сигнала любыми элементами заданного массива, используя значение типа TimeSpan для указания интервала времени. |
WaitAny(WaitHandle[], TimeSpan, Boolean) |
Ожидает получения сигнала какими-либо элементами заданного массива, используя TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitOne() |
Блокирует текущий поток до получения сигнала объектом WaitHandle. |
WaitOne(Int32) |
Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах. |
WaitOne(Int32, Boolean) |
Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitOne(TimeSpan) |
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для указания интервала времени. |
WaitOne(TimeSpan, Boolean) |
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
Явные реализации интерфейса
IDisposable.Dispose() |
Этот API поддерживает инфраструктуру продукта и не предназначен для использования непосредственно из программного кода. Освобождает все ресурсы, занятые модулем WaitHandle. |
Методы расширения
GetSafeWaitHandle(WaitHandle) |
Возвращает безопасный дескриптор для собственного дескриптора ожидания операционной системы. |
SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Задает безопасный дескриптор для собственного дескриптора ожидания операционной системы. |
Применяется к
Потокобезопасность
Данный тип потокобезопасен.