WaitHandle.WaitAny メソッド

定義

指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

オーバーロード

WaitAny(WaitHandle[])

指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

WaitAny(WaitHandle[], Int32)

32 ビット符号付き整数を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

WaitAny(WaitHandle[], TimeSpan)

TimeSpan を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

WaitAny(WaitHandle[], Int32, Boolean)

32 ビットの符号付き整数を使用して時間間隔を指定し、待機する前に同期ドメインを終了するかどうかを指定して、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

WaitAny(WaitHandle[], TimeSpan, Boolean)

指定した配列内のいずれかの要素がシグナルを受信するまで待機します。TimeSpan を使用して時間間隔を指定し、待機の前でも同期ドメインを終了するかどうかを指定します。

WaitAny(WaitHandle[])

指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles);
static member WaitAny : System.Threading.WaitHandle[] -> int
Public Shared Function WaitAny (waitHandles As WaitHandle()) As Integer

パラメーター

waitHandles
WaitHandle[]

現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。

戻り値

Int32

待機を実行するオブジェクトの配列インデックス。

例外

waitHandles パラメーターが null です。

  • または - waitHandles 配列内の 1 つ以上のオブジェクトが null です。

waitHandles のオブジェクトの数が、システムで許可されている範囲を超えています。

.NET Framework のバージョンが 1.0 または 1.1 であるにもかかわらず、waitHandles が要素のない配列です。

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

.NET Framework のバージョンが 2.0 以降であるにもかかわらず、waitHandles が要素のない配列です。

waitHandles 配列には、別のアプリケーション ドメインのWaitHandle の透過プロキシが含まれます。

次のコード例は、 メソッドの呼び出しを示 WaitAny しています。

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 tasks are 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).

注釈

AbandonedMutexExceptionは、.NET Framework バージョン 2.0 の新機能です。 以前のバージョンでは、ミューテックスが破棄されたため、待機が完了すると、 メソッド WaitAny true は を返します。 破棄されたミューテックスは、多くの場合、重大なコーディング エラーを示します。 システム全体のミューテックスの場合は、アプリケーションが突然終了された場合 (たとえば、システム全体のミューテックスを使用して) Windows タスク マネージャー。 例外には、デバッグに役立つ情報が含まれている。

メソッド WaitAny は、ミューテックスが破棄されたため、待機が完了した場合 AbandonedMutexException にのみ をスローします。 破棄されたミューテックスよりもインデックス番号が低い解放されたミューテックスが含まれている場合、メソッドは正常に完了し、例外 waitHandles WaitAny はスローされません。

注意

バージョン 2.0 より前の .NET Framework のバージョンでは、スレッドが を明示的に解放せずに終了または中止し、別のスレッドの配列のインデックス 0 (ゼロ) にある場合、 によって返されるインデックスは 0 ではなく Mutex Mutex WaitAny WaitAny 128 になります。

このメソッドは、ハンドルがシグナル処理された場合に を返します。 呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナルオブジェクトの最小インデックス値を持つシグナルオブジェクトの配列インデックスです。

待機ハンドルの最大数は 64 で、現在のスレッドが状態の場合は 63 STA です。

このメソッド オーバーロードを呼び出すのは、メソッド オーバーロードを呼び出し、 に -1 (または ) を 指定し、 に と WaitAny(WaitHandle[], Int32, Boolean) Timeout.Infinite millisecondsTimeout を指定するのと true 同じです exitContext

適用対象

WaitAny(WaitHandle[], Int32)

32 ビット符号付き整数を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAny : System.Threading.WaitHandle[] * int -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Integer

パラメーター

waitHandles
WaitHandle[]

現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。

millisecondsTimeout
Int32

待機するミリ秒数。無制限に待機する場合は Infinite (-1)。

戻り値

Int32

待機を実行したオブジェクトの配列インデックス。または、待機を実行したオブジェクトがなく millisecondsTimeout に等しい時間間隔が経過した場合は WaitTimeout となります。

例外

waitHandles パラメーターが null です。

  • または - waitHandles 配列内の 1 つ以上のオブジェクトが null です。

waitHandles のオブジェクトの数が、システムで許可されている範囲を超えています。

millisecondsTimeout は無限のタイムアウトを表す -1 以外の負の数です。

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

waitHandles は、要素を持たない配列です。

waitHandles 配列には、別のアプリケーション ドメインのWaitHandle の透過プロキシが含まれます。

注釈

millisecondsTimeout 0 の場合、 メソッドはブロックしない。 待機ハンドルの状態をテストし、すぐにを返します。

メソッド WaitAny は、ミューテックスが破棄されたため、待機が完了した場合 AbandonedMutexException にのみ をスローします。 破棄されたミューテックスよりもインデックス番号が低い解放されたミューテックスが含まれている場合、メソッドは正常に完了し、例外 waitHandles WaitAny はスローされません。

このメソッドは、いずれかのハンドルがシグナル状態にある場合、またはタイムアウトが発生した場合に、待機が終了すると を返します。 呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナルオブジェクトの最小インデックス値を持つシグナルオブジェクトの配列インデックスです。

待機ハンドルの最大数は 64 で、現在のスレッドが状態の場合は 63 STA です。

このメソッド オーバーロードの呼び出しは、 オーバーロードを呼び出 WaitAny(WaitHandle[], Int32, Boolean) し、 に を指定する場合と同 false じです exitContext

適用対象

WaitAny(WaitHandle[], TimeSpan)

TimeSpan を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan) As Integer

パラメーター

waitHandles
WaitHandle[]

現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。

timeout
TimeSpan

待機するミリ秒数を表す TimeSpan。無制限に待機する場合は、-1 ミリ秒を表す TimeSpan

戻り値

Int32

待機を実行したオブジェクトの配列インデックス。または、待機を実行したオブジェクトがなく timeout に等しい時間間隔が経過した場合は WaitTimeout となります。

例外

waitHandles パラメーターが null です。

  • または - waitHandles 配列内の 1 つ以上のオブジェクトが null です。

waitHandles のオブジェクトの数が、システムで許可されている範囲を超えています。

timeout は無限のタイムアウトを表す -1 ミリ秒以外の負の数です。 または timeoutMaxValue より大きくなっています。

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

waitHandles は、要素を持たない配列です。

waitHandles 配列には、別のアプリケーション ドメインのWaitHandle の透過プロキシが含まれます。

注釈

timeout 0 の場合、 メソッドはブロックしない。 待機ハンドルの状態をテストし、すぐにを返します。

メソッド WaitAny は、ミューテックスが破棄されたため、待機が完了した場合 AbandonedMutexException にのみ をスローします。 破棄されたミューテックスよりもインデックス番号が低い解放されたミューテックスが含まれている場合、メソッドは正常に完了し、例外 waitHandles WaitAny はスローされません。

このメソッドは、いずれかのハンドルがシグナル通知された場合、またはタイム アウトが発生した場合に、待機が終了すると を返します。 呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナルオブジェクトの最小インデックス値を持つシグナルオブジェクトの配列インデックスです。

待機ハンドルの最大数は 64 で、現在のスレッドが状態の場合は 63 STA です。

の最大値は timeout です Int32.MaxValue

このメソッド オーバーロードの呼び出しは、 オーバーロードを呼び出 WaitAny(WaitHandle[], TimeSpan, Boolean) し、 に を指定する場合と同 false じです exitContext

適用対象

WaitAny(WaitHandle[], Int32, Boolean)

32 ビットの符号付き整数を使用して時間間隔を指定し、待機する前に同期ドメインを終了するかどうかを指定して、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * int * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Integer

パラメーター

waitHandles
WaitHandle[]

現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。

millisecondsTimeout
Int32

待機するミリ秒数。無制限に待機する場合は Infinite (-1)。

exitContext
Boolean

待機する前にコンテキストの同期ドメインを終了し (同期されたコンテキスト内にいる場合)、後で再取得する場合は、true。それ以外の場合は false

戻り値

Int32

待機を実行したオブジェクトの配列インデックス。または、待機を実行したオブジェクトがなく millisecondsTimeout に等しい時間間隔が経過した場合は WaitTimeout となります。

例外

waitHandles パラメーターが null です。

  • または - waitHandles 配列内の 1 つ以上のオブジェクトが null です。

waitHandles のオブジェクトの数が、システムで許可されている範囲を超えています。

.NET Framework のバージョンが 1.0 または 1.1 であるにもかかわらず、waitHandles が要素のない配列です。

millisecondsTimeout は無限のタイムアウトを表す -1 以外の負の数です。

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

.NET Framework のバージョンが 2.0 以降であるにもかかわらず、waitHandles が要素のない配列です。

waitHandles 配列には、別のアプリケーション ドメインのWaitHandle の透過プロキシが含まれます。

次のコード例は、スレッド プールを使用して複数のディスク上のファイルを同時に検索する方法を示しています。 領域に関する考慮事項については、各ディスクのルート ディレクトリだけが検索されます。

using namespace System;
using namespace System::IO;
using namespace System::Threading;
ref class Search
{
private:

   // Maintain state information to pass to FindCallback.
   ref class State
   {
   public:
      AutoResetEvent^ autoEvent;
      String^ fileName;
      State( AutoResetEvent^ autoEvent, String^ fileName )
         : autoEvent( autoEvent ), fileName( fileName )
      {}

   };


public:
   array<AutoResetEvent^>^autoEvents;
   array<String^>^diskLetters;

   // Search for stateInfo->fileName.
   void FindCallback( Object^ state )
   {
      State^ stateInfo = dynamic_cast<State^>(state);
      
      // Signal if the file is found.
      if ( File::Exists( stateInfo->fileName ) )
      {
         stateInfo->autoEvent->Set();
      }
   }

   Search()
   {
      
      // Retrieve an array of disk letters.
      diskLetters = Environment::GetLogicalDrives();
      autoEvents = gcnew array<AutoResetEvent^>(diskLetters->Length);
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         autoEvents[ i ] = gcnew AutoResetEvent( false );

      }
   }


   // Search for fileName in the root directory of all disks.
   void FindFile( String^ fileName )
   {
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         Console::WriteLine(  "Searching for {0} on {1}.", fileName, diskLetters[ i ] );
         ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Search::FindCallback ), gcnew State( autoEvents[ i ],String::Concat( diskLetters[ i ], fileName ) ) );

      }
      
      // Wait for the first instance of the file to be found.
      int index = WaitHandle::WaitAny( autoEvents, 3000, false );
      if ( index == WaitHandle::WaitTimeout )
      {
         Console::WriteLine( "\n{0} not found.", fileName );
      }
      else
      {
         Console::WriteLine( "\n{0} found on {1}.", fileName, diskLetters[ index ] );
      }
   }

};

int main()
{
   Search^ search = gcnew Search;
   search->FindFile( "SomeFile.dat" );
}
using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(autoEvents, 3000, false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = _
            WaitHandle.WaitAny(autoEvents, 3000, False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

注釈

millisecondsTimeout 0 の場合、 メソッドはブロックしない。 待機ハンドルの状態をテストし、すぐにを返します。

AbandonedMutexExceptionは、.NET Framework バージョン 2.0 の新機能です。 以前のバージョンでは、ミューテックスが破棄されたため、待機が完了すると、 メソッド WaitAny true は を返します。 破棄されたミューテックスは、多くの場合、重大なコーディング エラーを示します。 システム全体のミューテックスの場合、アプリケーションが突然終了した可能性があります (たとえば、Windows タスク マネージャー を使用して)。 例外には、デバッグに役立つ情報が含まれている。

メソッド WaitAny は、ミューテックスが破棄されたため、待機が完了した場合 AbandonedMutexException にのみ をスローします。 破棄されたミューテックスよりもインデックス番号が低い解放されたミューテックスが含まれている場合、メソッドは正常に完了し、例外 waitHandles WaitAny はスローされません。

注意

バージョン 2.0 より前の .NET Framework のバージョンでは、スレッドが を明示的に解放せずに終了または中止し、別のスレッドの配列のインデックス 0 (ゼロ) にある場合、 によって返されるインデックスは 0 ではなく Mutex Mutex WaitAny WaitAny 128 になります。

このメソッドは、いずれかのハンドルがシグナル状態にある場合、またはタイムアウトが発生した場合に、待機が終了すると を返します。 呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナルオブジェクトの最小インデックス値を持つシグナルオブジェクトの配列インデックスです。

待機ハンドルの最大数は 64 で、現在のスレッドが状態の場合は 63 STA です。

コンテキストの終了に関する注意事項

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

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

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

適用対象

WaitAny(WaitHandle[], TimeSpan, Boolean)

指定した配列内のいずれかの要素がシグナルを受信するまで待機します。TimeSpan を使用して時間間隔を指定し、待機の前でも同期ドメインを終了するかどうかを指定します。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Integer

パラメーター

waitHandles
WaitHandle[]

現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。

timeout
TimeSpan

待機するミリ秒数を表す TimeSpan。無制限に待機する場合は、-1 ミリ秒を表す TimeSpan

exitContext
Boolean

待機する前にコンテキストの同期ドメインを終了し (同期されたコンテキスト内にいる場合)、後で再取得する場合は、true。それ以外の場合は false

戻り値

Int32

待機を実行したオブジェクトの配列インデックス。または、待機を実行したオブジェクトがなく timeout に等しい時間間隔が経過した場合は WaitTimeout となります。

例外

waitHandles パラメーターが null です。

  • または - waitHandles 配列内の 1 つ以上のオブジェクトが null です。

waitHandles のオブジェクトの数が、システムで許可されている範囲を超えています。

.NET Framework のバージョンが 1.0 または 1.1 であるにもかかわらず、waitHandles が要素のない配列です。

timeout は無限のタイムアウトを表す -1 ミリ秒以外の負の数です。 または timeoutMaxValue より大きくなっています。

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

.NET Framework のバージョンが 2.0 以降であるにもかかわらず、waitHandles が要素のない配列です。

waitHandles 配列には、別のアプリケーション ドメインのWaitHandle の透過プロキシが含まれます。

次のコード例は、スレッド プールを使用して複数のディスク上のファイルを同時に検索する方法を示しています。 領域に関する考慮事項については、各ディスクのルート ディレクトリだけが検索されます。

using namespace System;
using namespace System::IO;
using namespace System::Threading;
ref class Search
{
private:

   // Maintain state information to pass to FindCallback.
   ref class State
   {
   public:
      AutoResetEvent^ autoEvent;
      String^ fileName;
      State( AutoResetEvent^ autoEvent, String^ fileName )
         : autoEvent( autoEvent ), fileName( fileName )
      {}

   };


public:
   array<AutoResetEvent^>^autoEvents;
   array<String^>^diskLetters;

   // Search for stateInfo->fileName.
   void FindCallback( Object^ state )
   {
      State^ stateInfo = dynamic_cast<State^>(state);
      
      // Signal if the file is found.
      if ( File::Exists( stateInfo->fileName ) )
      {
         stateInfo->autoEvent->Set();
      }
   }

   Search()
   {
      
      // Retrieve an array of disk letters.
      diskLetters = Environment::GetLogicalDrives();
      autoEvents = gcnew array<AutoResetEvent^>(diskLetters->Length);
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         autoEvents[ i ] = gcnew AutoResetEvent( false );

      }
   }


   // Search for fileName in the root directory of all disks.
   void FindFile( String^ fileName )
   {
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         Console::WriteLine(  "Searching for {0} on {1}.", fileName, diskLetters[ i ] );
         ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Search::FindCallback ), gcnew State( autoEvents[ i ],String::Concat( diskLetters[ i ], fileName ) ) );

      }
      
      // Wait for the first instance of the file to be found.
      int index = WaitHandle::WaitAny( autoEvents, TimeSpan(0,0,3), false );
      if ( index == WaitHandle::WaitTimeout )
      {
         Console::WriteLine( "\n{0} not found.", fileName );
      }
      else
      {
         Console::WriteLine( "\n{0} found on {1}.", fileName, diskLetters[ index ] );
      }
   }

};

int main()
{
   Search^ search = gcnew Search;
   search->FindFile( "SomeFile.dat" );
}
using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(
            autoEvents, new TimeSpan(0, 0, 3), false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = WaitHandle.WaitAny( _
            autoEvents, New TimeSpan(0, 0, 3), False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

注釈

timeout 0 の場合、 メソッドはブロックしない。 待機ハンドルの状態をテストし、すぐにを返します。

AbandonedMutexExceptionは、.NET Framework バージョン 2.0 の新機能です。 以前のバージョンでは、ミューテックスが破棄されたため、待機が完了すると、 メソッド WaitAny true は を返します。 破棄されたミューテックスは、多くの場合、重大なコーディング エラーを示します。 システム全体のミューテックスの場合、アプリケーションが突然終了した可能性があります (たとえば、Windows タスク マネージャー を使用して)。 例外には、デバッグに役立つ情報が含まれている。

メソッド WaitAny は、ミューテックスが破棄されたため、待機が完了した場合 AbandonedMutexException にのみ をスローします。 破棄されたミューテックスよりもインデックス番号が低い解放されたミューテックスが含まれている場合、メソッドは正常に完了し、例外 waitHandles WaitAny はスローされません。

注意

バージョン 2.0 より前の .NET Framework のバージョンでは、スレッドが を明示的に解放せずに終了または中止し、別のスレッドの配列のインデックス 0 (ゼロ) にある場合、 によって返されるインデックスは 0 ではなく Mutex Mutex WaitAny WaitAny 128 になります。

このメソッドは、いずれかのハンドルがシグナル通知された場合、またはタイム アウトが発生した場合に、待機が終了すると を返します。 呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナルオブジェクトの最小インデックス値を持つシグナルオブジェクトの配列インデックスです。

待機ハンドルの最大数は 64 で、現在のスレッドが状態の場合は 63 STA です。

の最大値は timeout です Int32.MaxValue

コンテキストの終了に関する注意事項

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

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

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

適用対象