WaitHandle.WaitAll 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 semua elemen dalam array yang ditentukan untuk menerima sinyal.
Overload
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu. |
WaitAll(WaitHandle[], Int32, Boolean) |
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu. |
WaitAll(WaitHandle[], TimeSpan) |
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu. |
WaitAll(WaitHandle[], Int32) |
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu. |
WaitAll(WaitHandle[]) |
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Boolean
Parameter
- waitHandles
- WaitHandle[]
Array WaitHandle
yang berisi objek yang instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.
- 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
true
ketika setiap elemen di waitHandles
telah menerima sinyal; jika tidak false
.
Pengecualian
Parameternya waitHandles
adalah null
.
-atau-
Satu atau beberapa objek dalam waitHandles
array adalah null
.
-atau-
waitHandles
adalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.
Array waitHandles
berisi elemen yang merupakan duplikat.
Jumlah objek di waitHandles
lebih besar dari yang diizinkan sistem.
-atau-
Atribut STAThreadAttribute diterapkan ke prosedur utas untuk utas saat ini, dan waitHandles
berisi lebih dari satu elemen.
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 dihentikan karena utas keluar tanpa melepaskan mutex.
Array waitHandles
berisi proksi transparan untuk WaitHandle di domain aplikasi lain.
Contoh
Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item memberi sinyal dan kemudian keluar.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
int main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if ( WaitHandle::WaitAll( manualEvents, TimeSpan(0,0,5), false ) )
{
Console::WriteLine( "Files written - main exiting." );
}
else
{
// The wait operation times out.
Console::WriteLine( "Error writing files - main exiting." );
}
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if(WaitHandle.WaitAll(
manualEvents, new TimeSpan(0, 0, 5), false))
{
Console.WriteLine("Files written - main exiting.");
}
else
{
// The wait operation times out.
Console.WriteLine("Error writing files - main exiting.");
}
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
If WaitHandle.WaitAll( _
manualEvents, New TimeSpan(0, 0, 5), false) = True Then
Console.WriteLine("Files written - main exiting.")
Else
' The wait operation times out.
Console.WriteLine("Error writing files - main exiting.")
End If
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Keterangan
Jika timeout
nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.
Jika muteks ditinggalkan, akan AbandonedMutexException 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 WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti semua handel diberi sinyal atau waktu habis terjadi. Jika lebih dari 64 handel dilewati, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan akan gagal.
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
WaitAll(WaitHandle[], Int32, Boolean)
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
Menunggu semua elemen dalam array yang ditentukan menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * int * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Boolean
Parameter
- waitHandles
- WaitHandle[]
Array WaitHandle
yang berisi objek yang instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama (duplikat).
- 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
true
ketika setiap elemen di waitHandles
telah menerima sinyal; jika tidak, false
.
Pengecualian
Parameternya waitHandles
adalah null
.
-atau-
Satu atau beberapa objek dalam waitHandles
array adalah null
.
-atau-
waitHandles
adalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.
Array waitHandles
berisi elemen yang merupakan duplikat.
Jumlah objek di waitHandles
lebih besar dari yang diizinkan sistem.
-atau-
Utas saat ini dalam STA status , dan waitHandles
berisi lebih dari satu elemen.
waitHandles
adalah array tanpa elemen dan versi .NET Framework adalah 1.0 atau 1.1.
millisecondsTimeout
adalah angka negatif selain -1, yang menunjukkan waktu habis yang tak terbatas.
Penantian selesai karena utas keluar tanpa melepaskan mutex.
Array waitHandles
berisi proksi transparan untuk WaitHandle di domain aplikasi lain.
Contoh
Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item memberi sinyal dan kemudian keluar.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
int main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if ( WaitHandle::WaitAll( manualEvents, 5000, false ) )
{
Console::WriteLine( "Files written - main exiting." );
}
else
{
// The wait operation times out.
Console::WriteLine( "Error writing files - main exiting." );
}
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if(WaitHandle.WaitAll(manualEvents, 5000, false))
{
Console.WriteLine("Files written - main exiting.");
}
else
{
// The wait operation times out.
Console.WriteLine("Error writing files - main exiting.");
}
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
If WaitHandle.WaitAll(manualEvents, 5000, false) = True Then
Console.WriteLine("Files written - main exiting.")
Else
' The wait operation times out.
Console.WriteLine("Error writing files - main exiting.")
End If
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Keterangan
Jika millisecondsTimeout
nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.
Jika muteks ditinggalkan, akan AbandonedMutexException 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 WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti baik ketika semua handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari 64 handel dilewati, akan NotSupportedException dilemparkan. Jika ada duplikat dalam array, panggilan gagal dengan DuplicateWaitObjectException.
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
WaitAll(WaitHandle[], TimeSpan)
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan) As Boolean
Parameter
- waitHandles
- WaitHandle[]
Array WaitHandle
yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.
- timeout
- TimeSpan
TimeSpan yang mewakili jumlah milidetik untuk menunggu, atau TimeSpan yang mewakili -1 milidetik, untuk menunggu tanpa batas waktu.
Mengembalikan
true
ketika setiap elemen di waitHandles
telah menerima sinyal; jika tidak, false
.
Pengecualian
Parameternya waitHandles
adalah null
.
-atau-
Satu atau beberapa objek dalam waitHandles
array adalah null
.
-atau-
waitHandles
adalah array tanpa elemen.
Array waitHandles
berisi elemen yang merupakan duplikat.
Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.
Jumlah objek di waitHandles
lebih besar dari yang diizinkan sistem.
-atau-
Utas saat ini dalam STA status , dan waitHandles
berisi lebih dari satu elemen.
timeout
adalah angka negatif selain -1 milidetik, yang mewakili waktu habis yang tak terbatas.
-atau-
timeout
lebih besar dari Int32.MaxValue.
Penantian dihentikan karena utas keluar tanpa melepaskan mutex.
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 WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti semua handel diberi sinyal atau waktu habis terjadi. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan akan gagal.
Nilai maksimum untuk timeout
adalah Int32.MaxValue.
Memanggil metode ini kelebihan beban sama dengan memanggil WaitAll(WaitHandle[], TimeSpan, Boolean) kelebihan beban dan menentukan false
untuk exitContext
.
Berlaku untuk
WaitAll(WaitHandle[], Int32)
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAll : System.Threading.WaitHandle[] * int -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Boolean
Parameter
- waitHandles
- WaitHandle[]
Array WaitHandle
yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama (duplikat).
- millisecondsTimeout
- Int32
Jumlah milidetik untuk menunggu, atau Infinite (-1) untuk menunggu tanpa batas waktu.
Mengembalikan
true
ketika setiap elemen di waitHandles
telah menerima sinyal; jika tidak, false
.
Pengecualian
Parameternya waitHandles
adalah null
.
-atau-
Satu atau beberapa objek dalam waitHandles
array adalah null
.
-atau-
waitHandles
adalah array tanpa elemen.
Array waitHandles
berisi elemen yang merupakan duplikat.
Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.
Jumlah objek di waitHandles
lebih besar dari yang diizinkan sistem.
-atau-
Utas saat ini dalam STA status , dan waitHandles
berisi lebih dari satu elemen.
millisecondsTimeout
adalah angka negatif selain -1, yang mewakili waktu habis yang tak terbatas.
Penantian selesai karena utas keluar tanpa melepaskan mutex.
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 WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti ketika semua handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika ada duplikat dalam array, panggilan gagal dengan DuplicateWaitObjectException.
Memanggil metode ini kelebihan beban sama dengan memanggil WaitAll(WaitHandle[], Int32, Boolean) kelebihan beban dan menentukan false
untuk exitContext
.
Berlaku untuk
WaitAll(WaitHandle[])
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
- Sumber:
- WaitHandle.cs
Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);
static member WaitAll : System.Threading.WaitHandle[] -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle()) As Boolean
Parameter
- waitHandles
- WaitHandle[]
Array WaitHandle
yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.
Mengembalikan
true
ketika setiap elemen di waitHandles
telah menerima sinyal; jika tidak, metode tidak pernah kembali.
Pengecualian
Parameternya waitHandles
adalah null
. -atau-
Satu atau beberapa objek dalam waitHandles
array adalah null
.
-atau-
waitHandles
adalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.
Array waitHandles
berisi elemen yang merupakan duplikat.
Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.
Jumlah objek di waitHandles
lebih besar dari yang diizinkan sistem.
-atau-
Utas saat ini dalam STA status , dan waitHandles
berisi lebih dari satu elemen.
waitHandles
adalah array tanpa elemen dan versi .NET Framework adalah 1.0 atau 1.1.
Penantian dihentikan karena utas keluar tanpa melepaskan mutex.
Array waitHandles
berisi proksi transparan untuk WaitHandle di domain aplikasi lain.
Contoh
Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item untuk memberi sinyal dan kemudian keluar.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
void main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
WaitHandle::WaitAll( manualEvents );
Console::WriteLine( "Files written - main exiting." );
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
WaitHandle.WaitAll(manualEvents);
Console.WriteLine("Files written - main exiting.");
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
WaitHandle.WaitAll(manualEvents)
Console.WriteLine("Files written - main exiting.")
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Keterangan
AbandonedMutexException baru dalam .NET Framework versi 2.0. Di versi sebelumnya, WaitAll metode akan kembali true
saat 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 WaitAll mengembalikan ketika semua handel diberi sinyal. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan gagal dengan DuplicateWaitObjectException.
Memanggil metode ini kelebihan beban setara dengan memanggil WaitAll(WaitHandle[], Int32, Boolean) metode kelebihan beban dan menentukan -1 (atau Timeout.Infinite) untuk millisecondsTimeout
dan true
untuk exitContext
.