WaitHandle.WaitAll Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen.
Überlädt
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
WaitAll(WaitHandle[], Int32, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein Int32-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
WaitAll(WaitHandle[], TimeSpan) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an. |
WaitAll(WaitHandle[], Int32) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem Int32-Wert an. |
WaitAll(WaitHandle[]) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.
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[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.
- timeout
- TimeSpan
Eine TimeSpan-Struktur, die die Anzahl der zu Millisekunden für die Wartezeit angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden angibt, also eine unbeschränkte Wartezeit.
- exitContext
- Boolean
true
, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false
.
Gibt zurück
true
, wenn jedes Element in waitHandles
ein Signal empfangen hat, andernfalls false
.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
- oder -
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält doppelte Elemente.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
- oder -
Das STAThreadAttribute-Attribut wird für den aktuellen Thread auf die Threadprozedur angewendet, und waitHandles
enthält mehrere Elemente.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
timeout
ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.
- oder -
timeout
ist größer als Int32.MaxValue.
Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.
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
Hinweise
Wenn timeout
null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.
Wenn ein Mutex verlassen wird, wird ein AbandonedMutexException ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Die WaitAll -Methode gibt zurück, wenn die Wartezeit beendet wird. Dies bedeutet, dass entweder alle Handles signalisiert werden oder ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf fehl.
Der Maximalwert für timeout
ist Int32.MaxValue.
Beenden des Kontexts
Der exitContext
-Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf einer Instanz einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.
Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true
von für exitContext
, dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.
Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContext
angibttrue
, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.
Gilt für:
WaitAll(WaitHandle[], Int32, Boolean)
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein Int32-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.
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[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt (Duplikate) enthalten.
- millisecondsTimeout
- Int32
Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.
- exitContext
- Boolean
true
, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false
.
Gibt zurück
true
, wenn jedes Element in waitHandles
ein Signal empfangen hat, andernfalls false
.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
- oder -
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält doppelte Elemente.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
- oder -
Der aktuelle Thread ist im STA-Zustand, und waitHandles
enthält mehrere Elemente.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
millisecondsTimeout
ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.
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
Hinweise
Wenn millisecondsTimeout
null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.
Wenn ein Mutex verlassen wird, wird ein AbandonedMutexException ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Die WaitAll Methode gibt zurück, wenn die Wartezeit beendet wird, d. h. entweder, wenn alle Handles signalisiert werden oder wenn ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn im Array Duplikate vorhanden sind, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.
Beenden des Kontexts
Der exitContext
-Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf einer Instanz einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.
Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true
von für exitContext
, dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.
Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContext
angibttrue
, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.
Gilt für:
WaitAll(WaitHandle[], TimeSpan)
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an.
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[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.
- timeout
- TimeSpan
Eine TimeSpan-Struktur, die die Anzahl der zu Millisekunden für die Wartezeit angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden angibt, also eine unbeschränkte Wartezeit.
Gibt zurück
true
, wenn jedes Element in waitHandles
ein Signal empfangen hat, andernfalls false
.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
- oder -
waitHandles
ist ein Array ohne Elemente.
Das waitHandles
-Array enthält doppelte Elemente.
Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
- oder -
Der aktuelle Thread ist im STA-Zustand, und waitHandles
enthält mehrere Elemente.
timeout
ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.
- oder -
timeout
ist größer als Int32.MaxValue.
Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Hinweise
Wenn timeout
null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.
Die WaitAll -Methode gibt zurück, wenn die Wartezeit beendet wird. Dies bedeutet, dass entweder alle Handles signalisiert werden oder ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf fehl.
Der Maximalwert für timeout
ist Int32.MaxValue.
Das Aufrufen dieser Methodenüberladung ist identisch mit dem Aufrufen der WaitAll(WaitHandle[], TimeSpan, Boolean) Überladung und angeben false
für exitContext
.
Gilt für:
WaitAll(WaitHandle[], Int32)
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem Int32-Wert an.
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[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt (Duplikate) enthalten.
- millisecondsTimeout
- Int32
Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.
Gibt zurück
true
, wenn jedes Element in waitHandles
ein Signal empfangen hat, andernfalls false
.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
- oder -
waitHandles
ist ein Array ohne Elemente.
Das waitHandles
-Array enthält doppelte Elemente.
Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
- oder -
Der aktuelle Thread ist im STA-Zustand, und waitHandles
enthält mehrere Elemente.
millisecondsTimeout
ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Hinweise
Wenn millisecondsTimeout
null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.
Die WaitAll Methode gibt zurück, wenn die Wartezeit beendet wird, d. h. entweder, wenn alle Handles signalisiert werden oder wenn ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn im Array Duplikate vorhanden sind, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.
Das Aufrufen dieser Methodenüberladung ist identisch mit dem Aufrufen der WaitAll(WaitHandle[], Int32, Boolean) Überladung und angeben false
für exitContext
.
Gilt für:
WaitAll(WaitHandle[])
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen.
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[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.
Gibt zurück
true
, wenn jedes Element in waitHandles
ein Signal empfangen hat, andernfalls wird die Methode nicht beendet.
Ausnahmen
Der waitHandles
-Parameter ist null
. - oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
- oder -
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält doppelte Elemente.
Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
- oder -
Der aktuelle Thread ist im STA-Zustand, und waitHandles
enthält mehrere Elemente.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.
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
Hinweise
AbandonedMutexException ist neu in .NET Framework, Version 2.0. In früheren Versionen gibt die WaitAll Methode zurück true
, wenn ein Mutex abgebrochen wird. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Die WaitAll -Methode gibt zurück, wenn alle Handles signalisiert werden. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.
Das Aufrufen dieser Methodenüberladung entspricht dem Aufrufen der WaitAll(WaitHandle[], Int32, Boolean) Methodenüberladung und dem Angeben von -1 (oder Timeout.Infinite) für millisecondsTimeout
und true
.exitContext