WaitHandle.SignalAndWait メソッド

定義

1 つの WaitHandle を通知し、別のハンドルを待機します。

オーバーロード

SignalAndWait(WaitHandle, WaitHandle)

1 つの WaitHandle を通知し、別のハンドルを待機します。

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

1 つの WaitHandle を通知し、別のハンドルを待機します。タイムアウト間隔として 32 ビット符号付き整数を指定し、待機に入る前にコンテキストの同期ドメインを終了するかどうかを指定します。

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

1 つの WaitHandle を通知し、別のハンドルを待機します。タイムアウト間隔として TimeSpan を指定し、待機に入る前にコンテキストの同期ドメインを終了するかどうかを指定します。

SignalAndWait(WaitHandle, WaitHandle)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

1 つの 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 はセマフォで、カウントは既に最大値になっています。

スレッドがミューテックスを解放せずに終了したため、待機が完了しました。

次のコード例では、 メソッドオーバーロードをSignalAndWait(WaitHandle, WaitHandle)使用して、メイン スレッドがブロックされたスレッドを通知し、スレッドがタスクを完了するまで待機できるようにします。

この例では、5 つのスレッドを開始し、 フラグを使用EventResetMode.AutoResetして作成された でEventWaitHandleブロックし、ユーザーが Enter キーを押すたびに 1 つのスレッドを解放します。 次に、この例では、別の 5 つのスレッドをキューに入れ、 フラグでEventResetMode.ManualReset作成された をEventWaitHandle使用して、それらすべてを解放します。

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

1 つの 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 以外の負の数です。

スレッドがミューテックスを解放せずに終了したため、待機が完了しました。

注釈

この操作はアトミックであるとは限りません。 現在のスレッドがシグナル toSignal を受け取った後、待機する前に toWaitOn、別のプロセッサで実行されているスレッドがシグナル toWaitOn 通知を受け取ったり、待機したりする可能性があります。

が 0 の場合 millisecondsTimeout 、メソッドはブロックしません。 の状態 toWaitOn をテストし、すぐに返します。

コンテキストの終了

パラメーターは、既定以外の exitContext マネージド コンテキスト内からこのメソッドが呼び出されない限り、効果はありません。 スレッドが から ContextBoundObject派生したクラスのインスタンスの呼び出し内にある場合、マネージド コンテキストは既定以外の場合があります。 などString、 からContextBoundObject派生していないクラスでメソッドを現在実行している場合でも、 が現在のアプリケーション ドメイン内のスタック上にある場合ContextBoundObjectは、既定以外のコンテキストに存在できます。

コードが既定以外のコンテキストで実行されている場合、 をtrueexitContext指定すると、このメソッドを実行する前に、スレッドは既定以外のマネージド コンテキスト (つまり、既定のコンテキストに移行) を終了します。 このメソッドの呼び出しが完了すると、スレッドは元の既定以外のコンテキストに戻ります。

コンテキストを終了すると、コンテキスト バインド クラスに 属性がある場合に SynchronizationAttribute 便利です。 その場合、クラスのメンバーに対するすべての呼び出しが自動的に同期され、同期ドメインはクラスのコード本文全体になります。 メンバーの呼び出し履歴内のコードがこのメソッドを呼び出し、 に をexitContext指定trueすると、スレッドは同期ドメインを終了します。これにより、オブジェクトの任意のメンバーへの呼び出しでブロックされているスレッドを続行できます。 このメソッドが戻るときに、呼び出しを行ったスレッドは、同期ドメインの再入力を待機する必要があります。

適用対象

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

1 つの 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 以外の負のミリ秒値となります。

- または -

timeoutInt32.MaxValue より大きい。

スレッドがミューテックスを解放せずに終了したため、待機が完了しました。

注釈

この操作はアトミックであるとは限りません。 現在のスレッドがシグナル toSignal を受け取った後、待機する前に toWaitOn、別のプロセッサで実行されているスレッドがシグナル toWaitOn 通知を受け取ったり、待機したりする可能性があります。

timeout 最大値は です Int32.MaxValue

が 0 の場合 timeout 、メソッドはブロックしません。 の状態 toWaitOn をテストし、すぐに返します。

コンテキストの終了

パラメーターは、既定以外の exitContext マネージド コンテキスト内からこのメソッドが呼び出されない限り、効果はありません。 スレッドが から ContextBoundObject派生したクラスのインスタンスの呼び出し内にある場合、マネージド コンテキストは既定以外の場合があります。 などString、 からContextBoundObject派生していないクラスでメソッドを現在実行している場合でも、 が現在のアプリケーション ドメイン内のスタック上にある場合ContextBoundObjectは、既定以外のコンテキストに存在できます。

コードが既定以外のコンテキストで実行されている場合、 をtrueexitContext指定すると、このメソッドを実行する前に、スレッドは既定以外のマネージド コンテキスト (つまり、既定のコンテキストに移行) を終了します。 このメソッドの呼び出しが完了すると、スレッドは元の既定以外のコンテキストに戻ります。

コンテキストを終了すると、コンテキスト バインド クラスに 属性がある場合に SynchronizationAttribute 便利です。 その場合、クラスのメンバーに対するすべての呼び出しが自動的に同期され、同期ドメインはクラスのコード本文全体になります。 メンバーの呼び出し履歴内のコードがこのメソッドを呼び出し、 に をexitContext指定trueすると、スレッドは同期ドメインを終了します。これにより、オブジェクトの任意のメンバーへの呼び出しでブロックされているスレッドを続行できます。 このメソッドが戻るときに、呼び出しを行ったスレッドは、同期ドメインの再入力を待機する必要があります。

適用対象