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)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
向一个 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 -> boolPublic Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean参数
- toSignal
- WaitHandle
要发出信号的 WaitHandle。
- toWaitOn
- WaitHandle
要等待的 WaitHandle。
返回
如果信号和等待都成功完成,则为 true;如果等待没有完成,则此方法不返回。
例外
在一个处于 STA 状态的线程上调用了该方法。
              toSignal 是信号量,已达到最大计数。
等待结束,因为线程在未释放互斥的情况下退出。
示例
下面的代码示例使用 SignalAndWait(WaitHandle, WaitHandle) 方法重载允许main线程向阻塞的线程发出信号,然后等待线程完成任务。
该示例启动五个 EventWaitHandle 线程,允许它们阻止使用 EventResetMode.AutoReset 标志创建的 ,然后在用户每次按 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)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
向一个 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 -> boolPublic 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 的负数,而 -1 表示无限期超时。
等待结束,因为线程在未释放互斥的情况下退出。
注解
此操作不一定是原子操作。 在当前线程发出信号 toSignal 之后,但在等待 toWaitOn之前,在另一个处理器上运行的线程可能会发出信号 toWaitOn 或等待。
如果 millisecondsTimeout 为零,则该方法不会阻止。 它测试 的状态 toWaitOn 并立即返回。
退出上下文
除非 exitContext 从非默认托管上下文内部调用此方法,否则 参数无效。 如果线程位于对派生自 ContextBoundObject的类实例的调用内,则托管上下文可以是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中(如果 ContextBoundObject 位于当前应用程序域中的堆栈上)。
当代码在非默认上下文中执行时,将 指定 true 为 exitContext 会导致线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始非默认上下文。
当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。
适用于
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
向一个 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 -> boolPublic 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 是信号量,已达到最大计数。
等待结束,因为线程在未释放互斥的情况下退出。
注解
此操作不一定是原子操作。 在当前线程发出信号 toSignal 之后,但在等待 toWaitOn之前,在另一个处理器上运行的线程可能会发出信号 toWaitOn 或等待。
的 timeout 最大值为 Int32.MaxValue。
如果 timeout 为零,则该方法不会阻止。 它测试 的状态 toWaitOn 并立即返回。
退出上下文
除非 exitContext 从非默认托管上下文内部调用此方法,否则 参数无效。 如果线程位于对派生自 ContextBoundObject的类实例的调用内,则托管上下文可以是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中(如果 ContextBoundObject 位于当前应用程序域中的堆栈上)。
当代码在非默认上下文中执行时,将 指定 true 为 exitContext 会导致线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始非默认上下文。
当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。