WaitHandle.WaitAny Metode
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
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.
waitHandles
adalah array tanpa elemen, dan versi .NET Framework adalah 1.0 atau 1.1.
Penantian selesai karena utas keluar tanpa melepaskan mutex.
waitHandles
adalah 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.
waitHandles
adalah 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.
waitHandles
adalah 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.
waitHandles
adalah 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.
waitHandles
adalah 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.