WaitHandle.WaitAll Metoda
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy.
Przeciążenia
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Czeka na odbieranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem. |
WaitAll(WaitHandle[], Int32, Boolean) |
Czeka, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając Int32 wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem. |
WaitAll(WaitHandle[], TimeSpan) |
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu. |
WaitAll(WaitHandle[], Int32) |
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu Int32 wartości w celu określenia interwału czasu. |
WaitAll(WaitHandle[]) |
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Czeka na odbieranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.
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
Parametry
- waitHandles
- WaitHandle[]
Tablica WaitHandle
zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.
- timeout
- TimeSpan
Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy, aby czekać na czas nieokreślony.
- exitContext
- Boolean
true
aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false
.
Zwraca
true
gdy każdy element w waitHandles
elemecie otrzymał sygnał; w przeciwnym razie false
.
Wyjątki
Parametr waitHandles
to null
.
-lub-
Co najmniej jeden obiekt w tablicy waitHandles
to null
.
-lub-
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 2.0 lub nowsza.
Tablica waitHandles
zawiera elementy, które są duplikatami.
Liczba obiektów w obiekcie waitHandles
jest większa niż zezwala system.
-lub-
Atrybut STAThreadAttribute jest stosowany do procedury wątku dla bieżącego wątku i waitHandles
zawiera więcej niż jeden element.
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 1.0 lub 1.1.
timeout
jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.
-lub-
timeout
wartość jest większa niż Int32.MaxValue.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Tablica waitHandles
zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.
Przykłady
Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.
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
Uwagi
Jeśli timeout
jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.
Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że wszystkie uchwyty są sygnalizowane lub występuje przekroczenie limitu czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie zakończy się niepowodzeniem.
Wartość maksymalna to timeout
Int32.MaxValue.
Zamykanie kontekstu
Parametr exitContext
nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.
Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true
przyczynę exitContext
zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.
Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true
dla exitContext
elementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.
Dotyczy
WaitAll(WaitHandle[], Int32, Boolean)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Czeka, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając Int32 wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.
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
Parametry
- waitHandles
- WaitHandle[]
Tablica WaitHandle
zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu (duplikaty).
- exitContext
- Boolean
true
aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false
.
Zwraca
true
gdy każdy element w waitHandles
elemecie otrzymał sygnał; false
w przeciwnym razie .
Wyjątki
Parametr waitHandles
to null
.
-lub-
Co najmniej jeden obiekt w tablicy waitHandles
to null
.
-lub-
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 2.0 lub nowsza.
Tablica waitHandles
zawiera elementy, które są duplikatami.
Liczba obiektów w obiekcie waitHandles
jest większa niż zezwala system.
-lub-
Bieżący wątek jest w STA stanie i waitHandles
zawiera więcej niż jeden element.
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 1.0 lub 1.1.
millisecondsTimeout
jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Tablica waitHandles
zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.
Przykłady
Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.
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
Uwagi
Jeśli millisecondsTimeout
jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.
Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że gdy wszystkie uchwyty są sygnalizowane lub gdy wystąpi limit czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli w tablicy występują duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.
Zamykanie kontekstu
Parametr exitContext
nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.
Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true
przyczynę exitContext
zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.
Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true
dla exitContext
elementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.
Dotyczy
WaitAll(WaitHandle[], TimeSpan)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu.
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
Parametry
- waitHandles
- WaitHandle[]
Tablica WaitHandle
zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.
- timeout
- TimeSpan
Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy, aby czekać na czas nieokreślony.
Zwraca
true
gdy każdy element w waitHandles
elemecie otrzymał sygnał; false
w przeciwnym razie .
Wyjątki
Parametr waitHandles
to null
.
-lub-
Co najmniej jeden obiekt w tablicy waitHandles
to null
.
-lub-
waitHandles
jest tablicą bez elementów.
Tablica waitHandles
zawiera elementy, które są duplikatami.
Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.
Liczba obiektów w obiekcie waitHandles
jest większa niż zezwala system.
-lub-
Bieżący wątek jest w STA stanie i waitHandles
zawiera więcej niż jeden element.
timeout
jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.
-lub-
timeout
wartość jest większa niż Int32.MaxValue.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Tablica waitHandles
zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.
Uwagi
Jeśli timeout
jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.
Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że wszystkie uchwyty są sygnalizowane lub występuje przekroczenie limitu czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie zakończy się niepowodzeniem.
Wartość maksymalna to timeout
Int32.MaxValue.
Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitAll(WaitHandle[], TimeSpan, Boolean) przeciążenia i określanie false
wartości .exitContext
Dotyczy
WaitAll(WaitHandle[], Int32)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu Int32 wartości w celu określenia interwału czasu.
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
Parametry
- waitHandles
- WaitHandle[]
Tablica WaitHandle
zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu (duplikaty).
Zwraca
true
gdy każdy element w waitHandles
elemecie otrzymał sygnał; false
w przeciwnym razie .
Wyjątki
Parametr waitHandles
to null
.
-lub-
Co najmniej jeden obiekt w tablicy waitHandles
to null
.
-lub-
waitHandles
jest tablicą bez elementów.
Tablica waitHandles
zawiera elementy, które są duplikatami.
Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.
Liczba obiektów w obiekcie waitHandles
jest większa niż zezwala system.
-lub-
Bieżący wątek jest w STA stanie i waitHandles
zawiera więcej niż jeden element.
millisecondsTimeout
jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Tablica waitHandles
zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.
Uwagi
Jeśli millisecondsTimeout
jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.
Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że gdy wszystkie uchwyty są sygnalizowane lub gdy wystąpi limit czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli w tablicy występują duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.
Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitAll(WaitHandle[], Int32, Boolean) przeciążenia i określanie false
wartości .exitContext
Dotyczy
WaitAll(WaitHandle[])
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy.
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
Parametry
- waitHandles
- WaitHandle[]
Tablica WaitHandle
zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.
Zwraca
true
gdy każdy element w waitHandles
elemecie otrzymał sygnał; w przeciwnym razie metoda nigdy nie zwraca.
Wyjątki
Parametr waitHandles
to null
. -lub-
Co najmniej jeden obiekt w tablicy waitHandles
to null
.
-lub-
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 2.0 lub nowsza.
Tablica waitHandles
zawiera elementy, które są duplikatami.
Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.
Liczba obiektów w obiekcie waitHandles
jest większa niż zezwala system.
-lub-
Bieżący wątek jest w STA stanie i waitHandles
zawiera więcej niż jeden element.
waitHandles
jest tablicą bez elementów, a wersja programu .NET Framework to 1.0 lub 1.1.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Tablica waitHandles
zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.
Przykłady
Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.
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
Uwagi
AbandonedMutexException jest nowy w programie .NET Framework w wersji 2.0. W poprzednich wersjach metoda zwraca wartość true
po WaitAll porzuceniu mutexu. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Metoda WaitAll zwraca wartość , gdy wszystkie uchwyty są sygnalizowane. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.
Wywołanie tego przeciążenia metody jest równoważne wywołaniu WaitAll(WaitHandle[], Int32, Boolean) przeciążenia metody i określenie -1 (lub Timeout.Infinite) dla i true
dla exitContext
millisecondsTimeout
.