通过


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
继承
派生
属性
实现

示例

下面的代码示例演示了在主线程等待任务使用类的WaitHandle静态WaitAnyWaitAll方法完成任务时,两个线程如何执行后台任务。

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 的类包括:

线程可以通过调用派生自WaitHandle的类继承的实例方法WaitOne来阻止单个等待句柄上的线程。

其线程相关性不同派生的类 WaitHandle 。 事件等待句柄(EventWaitHandleAutoResetEventManualResetEvent)和信号灯没有线程相关性;任何线程都可以向事件等待句柄或信号灯发出信号。 另一方面,互斥体确实具有线程相关性;拥有 mutex 的线程必须释放它,如果线程在互斥体上调用 ReleaseMutex 该方法,则引发异常。

由于该 WaitHandle 类派生自 MarshalByRefObject,因此这些类可用于跨应用程序域边界同步线程的活动。

除了派生类之外, WaitHandle 该类还具有许多静态方法,这些方法会阻止线程,直到一个或多个同步对象收到信号。 这些包括:

  • SignalAndWait,它允许线程向一个等待句柄发出信号,并立即等待另一个句柄。

  • WaitAll,它允许线程等待,直到数组中的所有等待句柄接收信号。

  • WaitAny,它允许线程等待,直到发出一组指定等待句柄的任何一个信号。

这些方法的重载提供了放弃等待的超时间隔,并有机会在进入等待之前退出同步上下文,从而允许其他线程使用同步上下文。

重要

此类型实现 IDisposable 接口。 使用完类型或派生自它的类型后,应直接或间接释放它。 若要直接释放类型,请在块中Closetry/调用其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, Int32, Boolean)

发出一个 WaitHandle 信号并等待另一个,将超时间隔指定为 32 位有符号整数,并指定是否在输入等待之前退出上下文的同步域。

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

发出信号并等待另一个 WaitHandle ,将超时间隔指定为 TimeSpan 超时间隔,并指定是否在输入等待之前退出上下文的同步域。

SignalAndWait(WaitHandle, WaitHandle)

发出一个信号并等待另一 WaitHandle 个。

ToString()

返回一个表示当前对象的字符串。

(继承自 Object)
WaitAll(WaitHandle[], Int32, Boolean)

等待指定数组中的所有元素接收信号,使用 Int32 值指定时间间隔并指定是否在等待之前退出同步域。

WaitAll(WaitHandle[], Int32)

等待指定数组中的所有元素接收信号,并使用值 Int32 指定时间间隔。

WaitAll(WaitHandle[], TimeSpan, Boolean)

等待指定数组中的所有元素接收信号,使用 TimeSpan 值指定时间间隔,并指定是否在等待之前退出同步域。

WaitAll(WaitHandle[], TimeSpan)

等待指定数组中的所有元素接收信号,并使用 TimeSpan 值指定时间间隔。

WaitAll(WaitHandle[])

等待指定数组中的所有元素接收信号。

WaitAny(WaitHandle[], Int32, Boolean)

等待指定数组中的任何元素接收信号,使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。

WaitAny(WaitHandle[], Int32)

等待指定数组中的任何元素接收信号,使用 32 位带符号整数指定时间间隔。

WaitAny(WaitHandle[], TimeSpan, Boolean)

等待指定数组中的任何元素接收信号,使用指定 TimeSpan 时间间隔并指定是否在等待之前退出同步域。

WaitAny(WaitHandle[], TimeSpan)

等待指定数组中的任何元素接收信号,并使用指定 TimeSpan 时间间隔。

WaitAny(WaitHandle[])

等待指定数组中的任何元素接收信号。

WaitOne()

阻止当前线程,直到当前 WaitHandle 接收信号。

WaitOne(Int32, Boolean)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔,并指定是否在等待之前退出同步域。

WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔(以毫秒为单位)。

WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号,使用指定 TimeSpan 时间间隔并指定是否在等待之前退出同步域。

WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,并使用 TimeSpan 指定时间间隔。

显式接口实现

名称 说明
IDisposable.Dispose()

此 API 支持产品基础结构,不能在代码中直接使用。

释放该 WaitHandle命令使用的所有资源。

扩展方法

名称 说明
GetSafeWaitHandle(WaitHandle)

获取本机操作系统等待句柄的安全句柄。

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

设置本机操作系统等待句柄的安全句柄。

适用于

线程安全性

此类型是线程安全的。

另请参阅