WaitHandle 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
將等候共用資源獨佔存取權限的特定作業系統物件封裝起來。
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靜態WaitAny和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 及其衍生類別和 AutoResetEventManualResetEvent。
Semaphore 類別。 請參閱 Semaphore 和 SemaphoreSlim。
線程可以藉由呼叫 衍生自 WaitHandle的類別所繼承的實例方法WaitOne,封鎖個別等候句柄上的。
的 WaitHandle 衍生類別與其線程親和性不同。 事件等候句柄 (EventWaitHandle、 AutoResetEvent和) 和 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) |
設定原生作業系統等候控制代碼的安全控制代碼。 |
適用於
執行緒安全性
此型別具備執行緒安全。