WaitHandle.SignalAndWait 方法

定義

發出一個 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;如果未完成等候,則不會傳回這個方法。

例外狀況

toSignalnull

-或-

toWaitOnnull

該方法是在 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

millisecondsTimeout
Int32

整數,表示要等候的間隔。 如果值為 Infinite (亦即 -1),則會永遠等候。

exitContext
Boolean

true 表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false

傳回

如果順利完成信號發出和等候,則為 true;如果完成信號發出但等候逾時,則為 false

例外狀況

toSignalnull

-或-

toWaitOnnull

該方法是在 STA 狀態的執行緒上呼叫的。

無法對 WaitHandle 發出信號,因為它可能會超過最大計數。

millisecondsTimeout 為 -1 以外的負數,表示無限逾時。

由於執行緒結束時未釋放 Mutex,已完成等候。

備註

這項作業不保證是不可部分完成的。 在目前的線程發出訊 toSignal 號之後,但在等候 toWaitOn之前,在另一個處理器上執行的線程可能會發出訊號 toWaitOn 或等候。

如果 millisecondsTimeout 為零,則方法不會封鎖。 它會測試 的狀態 toWaitOn ,並立即傳回 。

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 true 會導致 exitContext 線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 trueexitContext,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。

適用於

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

timeout
TimeSpan

TimeSpan,代表要等候的間隔。 如果此值為 -1,則會無限期等候。

exitContext
Boolean

true 表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false

傳回

如果順利完成信號發出和等候,則為 true;如果完成信號發出但等候逾時,則為 false

例外狀況

toSignalnull

-或-

toWaitOnnull

該方法是在 STA 狀態的執行緒上呼叫的。

toSignal 為號誌,且已經有完整計數。

timeout 判定為 -1 以外的負毫秒數目。

-或-

timeout 大於 Int32.MaxValue

由於執行緒結束時未釋放 Mutex,已完成等候。

備註

這項作業不保證是不可部分完成的。 在目前的線程發出訊 toSignal 號之後,但在等候 toWaitOn之前,在另一個處理器上執行的線程可能會發出訊號 toWaitOn 或等候。

的最大值 timeoutInt32.MaxValue

如果 timeout 為零,則方法不會封鎖。 它會測試 的狀態 toWaitOn ,並立即傳回 。

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 true 會導致 exitContext 線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 trueexitContext,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。

適用於