WaitHandle.WaitAny Metode

Definisi

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal.

Overload

WaitAny(WaitHandle[])

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal.

WaitAny(WaitHandle[], Int32)

Menunggu salah satu elemen dalam array yang ditentukan menerima sinyal, menggunakan bilangan bulat bertanda tangan 32-bit untuk menentukan interval waktu.

WaitAny(WaitHandle[], TimeSpan)

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu.

WaitAny(WaitHandle[], Int32, Boolean)

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan bilangan bulat bertanda 32-bit untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

WaitAny(WaitHandle[])

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal.

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

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu.

Mengembalikan

Indeks array objek yang memenuhi penantian.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 1.0 atau 1.1.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan pemanggilan WaitAny metode .

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 task is 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).

Keterangan

AbandonedMutexExceptionbaru dalam .NET Framework versi 2.0. Di versi sebelumnya, WaitAny metode mengembalikan true jika penantian selesai karena mutex ditinggalkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode ini WaitAny hanya melempar AbandonedMutexException ketika penantian selesai karena mutex yang ditinggalkan. Jika waitHandles berisi mutex yang dirilis dengan nomor indeks yang lebih rendah daripada mutex yang ditinggalkan, WaitAny metode selesai secara normal dan pengecualian tidak dilemparkan.

Catatan

Dalam versi .NET Framework yang lebih lama dari versi 2.0, jika utas keluar atau dibatalkan tanpa secara eksplisit merilis Mutex, dan yang Mutex berada pada indeks 0 (nol) dalam WaitAny array pada utas lain, indeks yang dikembalikan oleh WaitAny adalah 128, bukan 0.

Metode ini kembali ketika ada handel yang disinyalir. Jika lebih dari satu objek menjadi sinyal selama panggilan, nilai yang dikembalikan adalah indeks array objek yang disinyalir dengan nilai indeks terkecil dari semua objek yang disinyalir.

Jumlah maksimum handel tunggu adalah 64, dan 63 jika utas saat ini dalam STA status.

Memanggil metode ini kelebihan beban setara dengan memanggil WaitAny(WaitHandle[], Int32, Boolean) metode kelebihan beban dan menentukan -1 (atau Timeout.Infinite) untuk millisecondsTimeout dan true untuk exitContext.

Berlaku untuk

WaitAny(WaitHandle[], Int32)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu salah satu elemen dalam array yang ditentukan menerima sinyal, menggunakan bilangan bulat bertanda tangan 32-bit untuk menentukan interval waktu.

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

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu.

millisecondsTimeout
Int32

Jumlah milidetik untuk menunggu, atau Infinite (-1) untuk menunggu tanpa batas waktu.

Mengembalikan

Indeks array objek yang memenuhi tunggu, atau WaitTimeout jika tidak ada objek yang memenuhi interval tunggu dan waktu yang setara dengan millisecondsTimeout telah berlalu.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

millisecondsTimeout adalah angka negatif selain -1, yang mewakili waktu habis yang tak terbatas.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

waitHandles adalah array tanpa elemen.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Keterangan

Jika millisecondsTimeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode ini WaitAny hanya melempar AbandonedMutexException ketika penantian selesai karena mutex yang ditinggalkan. Jika waitHandles berisi mutex yang dirilis dengan nomor indeks yang lebih rendah daripada mutex yang ditinggalkan, WaitAny metode selesai secara normal dan pengecualian tidak dilemparkan.

Metode ini kembali ketika waktu tunggu berakhir, baik ketika salah satu handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari satu objek menjadi sinyal selama panggilan, nilai yang dikembalikan adalah indeks array objek yang disinyalir dengan nilai indeks terkecil dari semua objek yang disinyalir.

Jumlah maksimum handel tunggu adalah 64, dan 63 jika utas saat ini dalam STA status.

Memanggil metode ini kelebihan beban sama dengan memanggil WaitAny(WaitHandle[], Int32, Boolean) kelebihan beban dan menentukan false untuk exitContext.

Berlaku untuk

WaitAny(WaitHandle[], TimeSpan)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu.

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

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu.

timeout
TimeSpan

TimeSpan yang mewakili jumlah milidetik untuk menunggu, atau TimeSpan yang mewakili -1 milidetik untuk menunggu tanpa batas waktu.

Mengembalikan

Indeks array objek yang memenuhi tunggu, atau WaitTimeout jika tidak ada objek yang memenuhi interval tunggu dan waktu yang setara dengan timeout telah berlalu.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

timeout adalah angka negatif selain -1 milidetik, yang mewakili waktu habis yang tak terbatas.

-atau-

timeout lebih besar dari Int32.MaxValue.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

waitHandles adalah array tanpa elemen.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Keterangan

Jika timeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode ini WaitAny hanya melempar AbandonedMutexException ketika penantian selesai karena mutex yang ditinggalkan. Jika waitHandles berisi mutex yang dirilis dengan nomor indeks yang lebih rendah daripada mutex yang ditinggalkan, WaitAny metode selesai secara normal dan pengecualian tidak dilemparkan.

Metode ini kembali ketika waktu tunggu berakhir, baik ketika salah satu handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari satu objek menjadi sinyal selama panggilan, nilai yang dikembalikan adalah indeks array objek yang disinyalir dengan nilai indeks terkecil dari semua objek yang disinyalir.

Jumlah maksimum handel tunggu adalah 64, dan 63 jika utas saat ini dalam STA status.

Nilai maksimum untuk timeout adalah Int32.MaxValue.

Memanggil metode ini kelebihan beban sama dengan memanggil WaitAny(WaitHandle[], TimeSpan, Boolean) kelebihan beban dan menentukan false untuk exitContext.

Berlaku untuk

WaitAny(WaitHandle[], Int32, Boolean)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan bilangan bulat bertanda 32-bit untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

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

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu.

millisecondsTimeout
Int32

Jumlah milidetik untuk menunggu, atau Infinite (-1) untuk menunggu tanpa batas waktu.

exitContext
Boolean

true untuk keluar dari domain sinkronisasi untuk konteks sebelum menunggu (jika dalam konteks yang disinkronkan), dan memperolehnya kembali setelahnya; jika tidak, false.

Mengembalikan

Indeks array objek yang memenuhi penantian, atau WaitTimeout jika tidak ada objek yang memenuhi interval tunggu dan waktu yang setara dengan millisecondsTimeout telah berlalu.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 1.0 atau 1.1.

millisecondsTimeout adalah angka negatif selain -1, yang mewakili waktu habis yang tak terbatas.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk secara bersamaan mencari file di beberapa disk. Untuk pertimbangan ruang, hanya direktori akar dari setiap disk yang dicari.

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

Keterangan

Jika millisecondsTimeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode ini WaitAny hanya melempar AbandonedMutexException ketika penantian selesai karena mutex yang ditinggalkan. Jika waitHandles berisi mutex yang dirilis dengan nomor indeks yang lebih rendah daripada mutex yang ditinggalkan, WaitAny metode selesai secara normal dan pengecualian tidak dilemparkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode ini kembali ketika waktu tunggu berakhir, baik ketika salah satu handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari satu objek menjadi sinyal selama panggilan, nilai yang dikembalikan adalah indeks array objek yang disinyalkan dengan nilai indeks terkecil dari semua objek yang disinyalkan.

Jumlah maksimum handel tunggu adalah 64, dan 63 jika utas saat ini dalam STA status.

Keluar dari konteks

Parameter exitContext tidak berpengaruh kecuali metode ini dipanggil dari dalam konteks terkelola nondefault. Konteks terkelola dapat menjadi nondefault jika utas Anda berada di dalam panggilan ke instans kelas yang berasal dari ContextBoundObject. Bahkan jika saat ini Anda menjalankan metode pada kelas yang tidak berasal dari ContextBoundObject, seperti String, Anda dapat berada dalam konteks nondefault jika ContextBoundObject ada di tumpukan Anda di domain aplikasi saat ini.

Saat kode Anda dijalankan dalam konteks nondefault, menentukan true penyebab exitContext utas keluar dari konteks terkelola nondefault (yaitu, untuk beralih ke konteks default) sebelum menjalankan metode ini. Utas kembali ke konteks nondefault asli setelah panggilan ke metode ini selesai.

Keluar dari konteks dapat berguna ketika kelas yang terikat konteks memiliki SynchronizationAttribute atribut . Dalam hal ini, semua panggilan ke anggota kelas secara otomatis disinkronkan, dan domain sinkronisasi adalah seluruh isi kode untuk kelas . Jika kode dalam tumpukan panggilan anggota memanggil metode ini dan menentukan untuk exitContext, utas true keluar dari domain sinkronisasi, yang memungkinkan utas yang diblokir pada panggilan ke anggota objek mana pun untuk melanjutkan. Ketika metode ini kembali, utas yang melakukan panggilan harus menunggu untuk masuk kembali ke domain sinkronisasi.

Berlaku untuk

WaitAny(WaitHandle[], TimeSpan, Boolean)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu salah satu elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

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

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek yang instans saat ini akan menunggu.

timeout
TimeSpan

TimeSpan yang menunjukkan jumlah milidetik untuk menunggu, atau TimeSpan yang mewakili -1 milidetik untuk menunggu tanpa batas waktu.

exitContext
Boolean

true untuk keluar dari domain sinkronisasi untuk konteks sebelum menunggu (jika dalam konteks yang disinkronkan), dan memperolehnya kembali setelahnya; jika tidak, false.

Mengembalikan

Indeks array objek yang memenuhi penantian, atau WaitTimeout jika tidak ada objek yang memenuhi interval tunggu dan waktu yang setara dengan timeout telah berlalu.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 1.0 atau 1.1.

timeout adalah angka negatif selain -1 milidetik, yang mewakili batas waktu tak terbatas.

-atau-

timeout lebih besar dari Int32.MaxValue.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

waitHandlesadalah array tanpa elemen, dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk secara bersamaan mencari file di beberapa disk. Untuk pertimbangan ruang, hanya direktori akar dari setiap disk yang dicari.

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

Keterangan

Jika timeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode ini WaitAny hanya melempar AbandonedMutexException ketika penantian selesai karena mutex yang ditinggalkan. Jika waitHandles berisi mutex yang dilepaskan dengan jumlah indeks yang lebih rendah dari mutex yang ditinggalkan, WaitAny metode selesai secara normal dan pengecualian tidak dilemparkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode ini kembali ketika waktu tunggu berakhir, baik ketika salah satu handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari satu objek menjadi sinyal selama panggilan, nilai yang dikembalikan adalah indeks array objek yang disinyalkan dengan nilai indeks terkecil dari semua objek yang disinyalkan.

Jumlah maksimum handel tunggu adalah 64, dan 63 jika utas saat ini dalam STA status.

Nilai maksimum untuk timeout adalah Int32.MaxValue.

Keluar dari konteks

Parameter exitContext tidak berpengaruh kecuali metode ini dipanggil dari dalam konteks terkelola nondefault. Konteks terkelola dapat menjadi nondefault jika utas Anda berada di dalam panggilan ke instans kelas yang berasal dari ContextBoundObject. Bahkan jika saat ini Anda menjalankan metode pada kelas yang tidak berasal dari ContextBoundObject, seperti String, Anda dapat berada dalam konteks nondefault jika ContextBoundObject ada di tumpukan Anda di domain aplikasi saat ini.

Saat kode Anda dijalankan dalam konteks nondefault, menentukan true penyebab exitContext utas keluar dari konteks terkelola nondefault (yaitu, untuk beralih ke konteks default) sebelum menjalankan metode ini. Utas kembali ke konteks nondefault asli setelah panggilan ke metode ini selesai.

Keluar dari konteks dapat berguna ketika kelas yang terikat konteks memiliki SynchronizationAttribute atribut . Dalam hal ini, semua panggilan ke anggota kelas secara otomatis disinkronkan, dan domain sinkronisasi adalah seluruh isi kode untuk kelas . Jika kode dalam tumpukan panggilan anggota memanggil metode ini dan menentukan untuk exitContext, utas true keluar dari domain sinkronisasi, yang memungkinkan utas yang diblokir pada panggilan ke anggota objek mana pun untuk melanjutkan. Ketika metode ini kembali, utas yang melakukan panggilan harus menunggu untuk masuk kembali ke domain sinkronisasi.

Berlaku untuk