WaitHandle 类

定义

封装等待对共享资源进行独占访问的操作系统特定的对象。Encapsulates operating system-specific objects that wait for exclusive access to shared resources.

public ref class WaitHandle abstract : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable
type WaitHandle = class
    inherit MarshalByRefObject
    interface IDisposable
Public MustInherit Class WaitHandle
Inherits MarshalByRefObject
Implements IDisposable
继承
派生
属性
实现

示例

下面的代码示例演示两个线程如何在主线程使用 @no__t 2 类的静态 @no__t 0 和 @no__t 方法等待任务完成时执行后台任务。The following code example shows how two threads can do background tasks while the Main thread waits for the tasks to complete using the static WaitAny and WaitAll methods of the WaitHandle class.

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 tasks are 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).

注解

@No__t-0 类封装本机操作系统同步句柄,用于表示运行时中允许多个等待操作的所有同步对象。The WaitHandle class encapsulates a native operating system synchronization handle and is used to represent all synchronization objects in the runtime that allow multiple wait operations. 有关等待句柄与其他同步对象的比较,请参阅同步基元概述For a comparison of wait handles with other synchronization objects, see Overview of Synchronization Primitives.

@No__t-0 类本身是抽象类。The WaitHandle class itself is abstract. 派生自 @no__t 的类将定义信号机制,以指示获取或释放对共享资源的访问,但它们使用继承的 @no__t 1 方法在等待访问共享资源时被阻止。Classes derived from WaitHandle define a signaling mechanism to indicate taking or releasing access to a shared resource, but they use the inherited WaitHandle methods to block while waiting for access to shared resources. 派生自 @no__t 的类包括:The classes derived from WaitHandle include:

线程可以通过调用实例方法来阻止单个等待句柄,WaitOne,该类由派生自 @no__t 的类继承。Threads can block on an individual wait handle by calling the instance method WaitOne, which is inherited by classes derived from WaitHandle.

@No__t 的派生类在其线程关联中有所不同。The derived classes of WaitHandle differ in their thread affinity. 事件等待句柄(EventWaitHandleAutoResetEventManualResetEvent)和信号量不具有线程关联;任何线程都可以通知事件等待句柄或信号量。Event wait handles (EventWaitHandle, AutoResetEvent, and ManualResetEvent) and semaphores do not have thread affinity; any thread can signal an event wait handle or semaphore. 另一方面,互斥体确实具有线程关联;拥有互斥体的线程必须释放它,如果线程对不属于它的互斥体调用 ReleaseMutex 方法,则将引发异常。Mutexes, on the other hand, do have thread affinity; the thread that owns a mutex must release it, and an exception is thrown if a thread calls the ReleaseMutex method on a mutex that it does not own.

由于 @no__t 0 类派生自 MarshalByRefObject,因此这些类可用于跨应用程序域边界同步线程的活动。Because the WaitHandle class derives from MarshalByRefObject, these classes can be used to synchronize the activities of threads across application domain boundaries.

除了其派生类之外,@no__t 0 类还具有许多静态方法,这些方法阻止线程,直到一个或多个同步对象收到信号。In addition to its derived classes, the WaitHandle class has a number of static methods that block a thread until one or more synchronization objects receive a signal. 这些方法包括:These include:

  • SignalAndWait,它允许线程向一个等待句柄发出信号,并立即等待另一个等待句柄。SignalAndWait, which allows a thread to signal one wait handle and immediately wait on another.

  • WaitAll,它允许线程等待,直到数组中的所有等待句柄都收到信号。WaitAll, which allows a thread to wait until all the wait handles in an array receive a signal.

  • WaitAny,它允许线程等待,直到指定的一组等待句柄发出信号。WaitAny, which allows a thread to wait until any one of a specified set of wait handles has been signaled.

这些方法的重载提供了放弃等待的超时间隔,以及在进入等待前退出同步上下文的机会,从而允许其他线程使用同步上下文。The overloads of these methods provide timeout intervals for abandoning the wait, and the opportunity to exit a synchronization context before entering the wait, allowing other threads to use the synchronization context.

重要

此类型实现 IDisposable 接口。This type implements the IDisposable interface. 使用完类型或派生自该类型的类型后,应直接或间接释放它。When you have finished using the type or a type derived from it, you should dispose of it either directly or indirectly. 若要直接释放类型,请在 try/catch 块中调用其 Close 方法。To dispose of the type directly, call its Close method in a try/catch block. 若要间接释放类型,请使用 using(在 C# 中)或 Using(在 Visual Basic 中)等语言构造。To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). 有关详细信息,请参阅 IDisposable 接口主题中的“使用实现 IDisposable 的对象”一节。For more information, see the "Using an Object that Implements IDisposable" section in the IDisposable interface topic.

WaitHandle 实现 @no__t 模式。WaitHandle implements the Dispose pattern. 请参阅 [实现 Dispose 方法] (~/docs/standard/garbage-collection/implementing-dispose)。See [Implementing a Dispose method](~/docs/standard/garbage-collection/implementing-dispose .md). 从 @no__t 派生时,请使用 @no__t 属性来存储本机操作系统句柄。When you derive from WaitHandle, use the SafeWaitHandle property to store your native operating system handle. 除非使用其他非托管资源,否则不需要重写受保护的 Dispose 方法。You do not need to override the protected Dispose method unless you use additional unmanaged resources.

构造函数

WaitHandle()

初始化 WaitHandle 类的新实例。Initializes a new instance of the WaitHandle class.

字段

InvalidHandle

表示无效的本机操作系统句柄。Represents an invalid native operating system handle. 此字段为只读。This field is read-only.

WaitTimeout

指示在任何等待句柄终止之前 WaitAny(WaitHandle[], Int32, Boolean) 操作已超时。Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. 此字段为常数。This field is constant.

属性

Handle

获取或设置本机操作系统句柄。Gets or sets the native operating system handle.

SafeWaitHandle

获取或设置本机操作系统句柄。Gets or sets the native operating system handle.

方法

Close()

释放由当前 WaitHandle 占用的所有资源。Releases all resources held by the current WaitHandle.

CreateObjRef(Type)

创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

(继承自 MarshalByRefObject)
Dispose()

释放 WaitHandle 类的当前实例所使用的所有资源。Releases all resources used by the current instance of the WaitHandle class.

Dispose(Boolean)

当在派生类中重写时,释放 WaitHandle 使用的非托管资源,并且可选择释放托管资源。When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
Finalize()

释放由当前实例所持有的资源。Releases the resources held by the current instance.

GetHashCode()

用作默认哈希函数。Serves as the default hash function.

(继承自 Object)
GetLifetimeService()

检索控制此实例的生存期策略的当前生存期服务对象。Retrieves the current lifetime service object that controls the lifetime policy for this instance.

(继承自 MarshalByRefObject)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
InitializeLifetimeService()

获取生存期服务对象来控制此实例的生存期策略。Obtains a lifetime service object to control the lifetime policy for this instance.

(继承自 MarshalByRefObject)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
MemberwiseClone(Boolean)

创建当前 MarshalByRefObject 对象的浅表副本。Creates a shallow copy of the current MarshalByRefObject object.

(继承自 MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

向一个 WaitHandle 发出信号并等待另一个。Signals one WaitHandle and waits on another.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

向一个 WaitHandle 发出信号并等待另一个,指定超时间隔为 32 位有符号整数,并指定在进入等待前是否退出上下文的同步域。Signals one WaitHandle and waits on another, specifying a time-out interval as a 32-bit signed integer and specifying whether to exit the synchronization domain for the context before entering the wait.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

向一个 WaitHandle 发出信号并等待另一个,指定超时间隔为 TimeSpan,并指定在进入等待前是否退出上下文的同步域。Signals one WaitHandle and waits on another, specifying the time-out interval as a TimeSpan and specifying whether to exit the synchronization domain for the context before entering the wait.

ToString()

返回一个表示当前对象的 string。Returns a string that represents the current object.

(继承自 Object)
WaitAll(WaitHandle[])

等待指定数组中的所有元素都收到信号。Waits for all the elements in the specified array to receive a signal.

WaitAll(WaitHandle[], Int32)

等待指定数组中的所有元素接收信号,同时使用 Int32 值指定时间间隔。Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval.

WaitAll(WaitHandle[], Int32, Boolean)

等待指定数组中的所有元素收到信号,使用 Int32 值指定时间间隔,并指定是否在等待之前退出同步域。Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitAll(WaitHandle[], TimeSpan)

等待指定数组中的所有元素接收信号,同时使用 TimeSpan 值指定时间间隔。Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval.

WaitAll(WaitHandle[], TimeSpan, Boolean)

等待指定数组中的所有元素收到信号,使用 TimeSpan 值指定时间间隔,并指定是否在等待之前退出同步域。Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval, and specifying whether to exit the synchronization domain before the wait.

WaitAny(WaitHandle[])

等待指定数组中的任一元素收到信号。Waits for any of the elements in the specified array to receive a signal.

WaitAny(WaitHandle[], Int32)

等待指定数组中的任意元素接收信号,同时使用 32 位有符号整数指定时间间隔。Waits for any of the elements in the specified array to receive a signal, using a 32-bit signed integer to specify the time interval.

WaitAny(WaitHandle[], Int32, Boolean)

等待指定数组中的任一元素收到信号,使用 32 位带符号整数指定时间间隔并指定是否在等待之前退出同步域。Waits for any of the elements in the specified array to receive a signal, using a 32-bit signed integer to specify the time interval, and specifying whether to exit the synchronization domain before the wait.

WaitAny(WaitHandle[], TimeSpan)

等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔。Waits for any of the elements in the specified array to receive a signal, using a TimeSpan to specify the time interval.

WaitAny(WaitHandle[], TimeSpan, Boolean)

等待指定数组中的任一元素收到信号,使用 TimeSpan 指定时间间隔并指定是否在等待之前退出同步域。Waits for any of the elements in the specified array to receive a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitOne()

阻止当前线程,直到当前 WaitHandle 收到信号。Blocks the current thread until the current WaitHandle receives a signal.

WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

WaitOne(Int32, Boolean)

阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

显式界面实现

IDisposable.Dispose()

释放由 WaitHandle 使用的所有资源。Releases all resources used by the WaitHandle.

扩展方法

GetSafeWaitHandle(WaitHandle)

获取本机操作系统等待句柄的安全句柄。Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

设置本机操作系统等待句柄的安全句柄。Sets a safe handle for a native operating system wait handle.

适用于

线程安全性

此类型是线程安全的。This type is thread safe.

另请参阅