WaitHandle.SignalAndWait 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
發出一個 WaitHandle 信號並等候另一個。
多載
SignalAndWait(WaitHandle, WaitHandle) |
發出一個 WaitHandle 信號並等候另一個。 |
SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean) |
發出一個 WaitHandle 信號並等候另一個,將逾時間隔指定為 32 位元帶正負號的整數,並指定是否要先離開內容的同步處理網域,再進入等候狀態。 |
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean) |
發出一個 WaitHandle 信號並等候另一個,將逾時間隔指定為 TimeSpan,並指定是否要先離開內容的同步處理網域,再進入等候狀態。 |
SignalAndWait(WaitHandle, WaitHandle)
發出一個 WaitHandle 信號並等候另一個。
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
參數
- toSignal
- WaitHandle
要發出的 WaitHandle 信號。
- toWaitOn
- WaitHandle
要等候的 WaitHandle。
傳回
如果順利完成信號發出和等候,則為 true
;如果未完成等候,則不會傳回這個方法。
例外狀況
該方法是在 STA 狀態的執行緒上呼叫的。
toSignal
為號誌,且已經有完整計數。
由於執行緒結束時未釋放 Mutex,已完成等候。
範例
下列程式代碼範例會 SignalAndWait(WaitHandle, WaitHandle) 使用 方法多載來允許主線程發出封鎖線程的訊號,然後等候線程完成工作。
此範例會啟動五個線程,允許他們在使用 EventResetMode.AutoReset 旗標建立的 EventWaitHandle 上封鎖,然後在使用者每次按下 ENTER 鍵時釋放一個線程。 接著,此範例會排入其他五個線程,並使用搭配 EventWaitHandle 旗標建立的 EventResetMode.ManualReset 釋放它們。
using namespace System;
using namespace System::Threading;
public ref class Example
{
private:
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
static EventWaitHandle^ ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
static __int64 threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
static EventWaitHandle^ clearCount =
gcnew EventWaitHandle( false,EventResetMode::AutoReset );
public:
[MTAThread]
static void main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = gcnew EventWaitHandle( false,EventResetMode::AutoReset );
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for ( int i = 0; i <= 4; i++ )
{
Thread^ t = gcnew Thread(
gcnew ParameterizedThreadStart( ThreadProc ) );
t->Start( i );
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while ( Interlocked::Read( threadCount ) < 5 )
{
Thread::Sleep( 500 );
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while ( Interlocked::Read( threadCount ) > 0 )
{
Console::WriteLine( L"Press ENTER to release a waiting thread." );
Console::ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle::SignalAndWait( ewh, clearCount );
}
Console::WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = gcnew EventWaitHandle( false,EventResetMode::ManualReset );
// Create and start five more numbered threads.
//
for ( int i = 0; i <= 4; i++ )
{
Thread^ t = gcnew Thread(
gcnew ParameterizedThreadStart( ThreadProc ) );
t->Start( i );
}
// Wait until all the threads have started and blocked.
//
while ( Interlocked::Read( threadCount ) < 5 )
{
Thread::Sleep( 500 );
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console::WriteLine( L"Press ENTER to release the waiting threads." );
Console::ReadLine();
ewh->Set();
}
static void ThreadProc( Object^ data )
{
int index = static_cast<Int32>(data);
Console::WriteLine( L"Thread {0} blocks.", data );
// Increment the count of blocked threads.
Interlocked::Increment( threadCount );
// Wait on the EventWaitHandle.
ewh->WaitOne();
Console::WriteLine( L"Thread {0} exits.", data );
// Decrement the count of blocked threads.
Interlocked::Decrement( threadCount );
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount->Set();
}
};
using System;
using System.Threading;
public class Example
{
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
private static EventWaitHandle ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
private static long threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
private static EventWaitHandle clearCount =
new EventWaitHandle(false, EventResetMode.AutoReset);
[MTAThread]
public static void Main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for (int i = 0; i <= 4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while (Interlocked.Read(ref threadCount) > 0)
{
Console.WriteLine("Press ENTER to release a waiting thread.");
Console.ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle.SignalAndWait(ewh, clearCount);
}
Console.WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
// Create and start five more numbered threads.
//
for(int i=0; i<=4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console.WriteLine("Press ENTER to release the waiting threads.");
Console.ReadLine();
ewh.Set();
}
public static void ThreadProc(object data)
{
int index = (int) data;
Console.WriteLine("Thread {0} blocks.", data);
// Increment the count of blocked threads.
Interlocked.Increment(ref threadCount);
// Wait on the EventWaitHandle.
ewh.WaitOne();
Console.WriteLine("Thread {0} exits.", data);
// Decrement the count of blocked threads.
Interlocked.Decrement(ref threadCount);
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount.Set();
}
}
Imports System.Threading
Public Class Example
' The EventWaitHandle used to demonstrate the difference
' between AutoReset and ManualReset synchronization events.
'
Private Shared ewh As EventWaitHandle
' A counter to make sure all threads are started and
' blocked before any are released. A Long is used to show
' the use of the 64-bit Interlocked methods.
'
Private Shared threadCount As Long = 0
' An AutoReset event that allows the main thread to block
' until an exiting thread has decremented the count.
'
Private Shared clearCount As New EventWaitHandle(False, _
EventResetMode.AutoReset)
<MTAThread> _
Public Shared Sub Main()
' Create an AutoReset EventWaitHandle.
'
ewh = New EventWaitHandle(False, EventResetMode.AutoReset)
' Create and start five numbered threads. Use the
' ParameterizedThreadStart delegate, so the thread
' number can be passed as an argument to the Start
' method.
For i As Integer = 0 To 4
Dim t As New Thread(AddressOf ThreadProc)
t.Start(i)
Next i
' Wait until all the threads have started and blocked.
' When multiple threads use a 64-bit value on a 32-bit
' system, you must access the value through the
' Interlocked class to guarantee thread safety.
'
While Interlocked.Read(threadCount) < 5
Thread.Sleep(500)
End While
' Release one thread each time the user presses ENTER,
' until all threads have been released.
'
While Interlocked.Read(threadCount) > 0
Console.WriteLine("Press ENTER to release a waiting thread.")
Console.ReadLine()
' SignalAndWait signals the EventWaitHandle, which
' releases exactly one thread before resetting,
' because it was created with AutoReset mode.
' SignalAndWait then blocks on clearCount, to
' allow the signaled thread to decrement the count
' before looping again.
'
WaitHandle.SignalAndWait(ewh, clearCount)
End While
Console.WriteLine()
' Create a ManualReset EventWaitHandle.
'
ewh = New EventWaitHandle(False, EventResetMode.ManualReset)
' Create and start five more numbered threads.
'
For i As Integer = 0 To 4
Dim t As New Thread(AddressOf ThreadProc)
t.Start(i)
Next i
' Wait until all the threads have started and blocked.
'
While Interlocked.Read(threadCount) < 5
Thread.Sleep(500)
End While
' Because the EventWaitHandle was created with
' ManualReset mode, signaling it releases all the
' waiting threads.
'
Console.WriteLine("Press ENTER to release the waiting threads.")
Console.ReadLine()
ewh.Set()
End Sub
Public Shared Sub ThreadProc(ByVal data As Object)
Dim index As Integer = CInt(data)
Console.WriteLine("Thread {0} blocks.", data)
' Increment the count of blocked threads.
Interlocked.Increment(threadCount)
' Wait on the EventWaitHandle.
ewh.WaitOne()
Console.WriteLine("Thread {0} exits.", data)
' Decrement the count of blocked threads.
Interlocked.Decrement(threadCount)
' After signaling ewh, the main thread blocks on
' clearCount until the signaled thread has
' decremented the count. Signal it now.
'
clearCount.Set()
End Sub
End Class
備註
這項作業不保證是不可部分完成的。 在目前的線程發出訊 toSignal
號之後,但在等候 toWaitOn
之前,在另一個處理器上執行的線程可能會發出訊號 toWaitOn
或等候。
適用於
SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)
發出一個 WaitHandle 信號並等候另一個,將逾時間隔指定為 32 位元帶正負號的整數,並指定是否要先離開內容的同步處理網域,再進入等候狀態。
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn, int millisecondsTimeout, bool exitContext);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, int millisecondsTimeout, bool exitContext);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle * int * bool -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As Integer, exitContext As Boolean) As Boolean
參數
- toSignal
- WaitHandle
要發出的 WaitHandle 信號。
- toWaitOn
- WaitHandle
要等候的 WaitHandle。
- exitContext
- Boolean
true
表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false
。
傳回
如果順利完成信號發出和等候,則為 true
;如果完成信號發出但等候逾時,則為 false
例外狀況
該方法是在 STA 狀態的執行緒上呼叫的。
無法對 WaitHandle 發出信號,因為它可能會超過最大計數。
millisecondsTimeout
為 -1 以外的負數,表示無限逾時。
由於執行緒結束時未釋放 Mutex,已完成等候。
備註
這項作業不保證是不可部分完成的。 在目前的線程發出訊 toSignal
號之後,但在等候 toWaitOn
之前,在另一個處理器上執行的線程可能會發出訊號 toWaitOn
或等候。
如果 millisecondsTimeout
為零,則方法不會封鎖。 它會測試 的狀態 toWaitOn
,並立即傳回 。
結束內容
exitContext
除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。
當您的程式代碼在非預設內容中執行時,指定 true
會導致 exitContext
線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。
當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 true
exitContext
,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。
適用於
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)
發出一個 WaitHandle 信號並等候另一個,將逾時間隔指定為 TimeSpan,並指定是否要先離開內容的同步處理網域,再進入等候狀態。
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn, TimeSpan timeout, bool exitContext);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, TimeSpan timeout, bool exitContext);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle * TimeSpan * bool -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As TimeSpan, exitContext As Boolean) As Boolean
參數
- toSignal
- WaitHandle
要發出的 WaitHandle 信號。
- toWaitOn
- WaitHandle
要等候的 WaitHandle。
- exitContext
- Boolean
true
表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false
。
傳回
如果順利完成信號發出和等候,則為 true
;如果完成信號發出但等候逾時,則為 false
例外狀況
該方法是在 STA 狀態的執行緒上呼叫的。
toSignal
為號誌,且已經有完整計數。
由於執行緒結束時未釋放 Mutex,已完成等候。
備註
這項作業不保證是不可部分完成的。 在目前的線程發出訊 toSignal
號之後,但在等候 toWaitOn
之前,在另一個處理器上執行的線程可能會發出訊號 toWaitOn
或等候。
的最大值 timeout
為 Int32.MaxValue。
如果 timeout
為零,則方法不會封鎖。 它會測試 的狀態 toWaitOn
,並立即傳回 。
結束內容
exitContext
除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。
當您的程式代碼在非預設內容中執行時,指定 true
會導致 exitContext
線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。
當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 true
exitContext
,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。