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
繼承
衍生
屬性
實作

範例

下列程式代碼範例顯示兩個線程如何在Main線程等候工作使用 類別的WaitHandle靜態WaitAnyWaitAll方法完成工作時執行背景工作。

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

線程可以藉由呼叫 衍生自 WaitHandle的類別所繼承的實例方法WaitOne,封鎖個別等候句柄上的。

WaitHandle 衍生類別與其線程親和性不同。 事件等候句柄 (EventWaitHandleAutoResetEvent和) 和 ManualResetEvent 號誌沒有線程親和性;任何線程都可以發出事件等候句柄或號誌的訊號。 另一方面,Mutex 具有線程親和性;擁有 Mutex 的線程必須釋放它,如果線程在它不擁有的 Mutex 上呼叫 ReleaseMutex 方法,就會擲回例外狀況。

由於類別 WaitHandle 衍生自 MarshalByRefObject,因此這些類別可用來同步處理跨應用程式域界限之線程的活動。

除了其衍生類別之外,類別 WaitHandle 還有一些靜態方法會封鎖線程,直到一或多個同步處理物件收到訊號為止。 它們包括:

  • SignalAndWait,可讓線程發出一個等候句柄的訊號,並立即等候另一個句柄。

  • WaitAll,可讓線程等候陣列中的所有等候句柄接收訊號。

  • WaitAny,可讓線程等到任何一組指定的等候句柄收到訊號為止。

這些方法的多載會提供放棄等候的逾時間隔,以及在進入等候之前結束同步處理內容的機會,讓其他線程能夠使用同步處理內容。

重要

此型別代表 IDisposable 介面。 當您完成使用型別或衍生自它的型別時,應該直接或間接處置它。 若要直接處置型別,請呼叫其 try/catch 區塊中的 Close 方法。 若要間接處置它,請使用語言建構函式,例如 using (在 C# 中) 或 Using (在 Visual Basic 中)。 如需詳細資訊,請參閱 IDisposable 介面文章中的<使用實作 IDisposable 的物件>一節。

WaitHandle 會實作 Dispose 模式。 請參閱 實作 Dispose 方法。 當您衍生自 WaitHandle時,請使用 SafeWaitHandle 屬性來儲存原生操作系統句柄。 除非您使用其他非受控資源,否則不需要覆寫受保護的 Dispose 方法。

建構函式

WaitHandle()

初始化 WaitHandle 類別的新執行個體。

欄位

InvalidHandle

代表無效的原生作業系統控制代碼。 此欄位為唯讀。

WaitTimeout

表示 WaitAny(WaitHandle[], Int32, Boolean) 作業在發出任何等候控制代碼信號之前便已逾時。 這個欄位為常數。

屬性

Handle
已淘汰.
已淘汰.

取得或設定原生 (Native) 的作業系統控制代碼。

SafeWaitHandle

取得或設定原生 (Native) 的作業系統控制代碼。

方法

Close()

釋放目前 WaitHandle 所持有的全部資源。

CreateObjRef(Type)

建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。

(繼承來源 MarshalByRefObject)
Dispose()

釋放 WaitHandle 類別目前的執行個體所使用的全部資源。

Dispose(Boolean)

當在衍生類別中覆寫時,釋放 WaitHandle 所使用的 Unmanaged 資源,並選擇性釋放 Managed 資源。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
Finalize()

將目前執行個體所持有的資源釋出。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetLifetimeService()
已淘汰.

擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。

(繼承來源 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 位元帶正負號的整數 (Signed Integer) 來指定時間間隔,並指定是否在等候之前先離開同步處理領域。

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)

設定原生作業系統等候控制代碼的安全控制代碼。

適用於

執行緒安全性

此型別具備執行緒安全。

另請參閱