WaitHandle.WaitAll Metodo
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Attende che tutti gli elementi nella matrice specificata ricevano un segnale.
Overload
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa. |
WaitAll(WaitHandle[], Int32, Boolean) |
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa. |
WaitAll(WaitHandle[], TimeSpan) |
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo. |
WaitAll(WaitHandle[], Int32) |
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo. |
WaitAll(WaitHandle[]) |
Attende che tutti gli elementi nella matrice specificata ricevano un segnale. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.
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
Parametri
- waitHandles
- WaitHandle[]
Matrice WaitHandle
contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.
- timeout
- TimeSpan
Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.
- exitContext
- Boolean
true
per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false
.
Restituisce
true
quando ogni elemento in waitHandles
ha ricevuto un segnale; in caso contrario false
.
Eccezioni
Il valore del parametro waitHandles
è null
.
-oppure-
Uno o più oggetti nella matrice waitHandles
sono null
.
-oppure-
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.
La matrice waitHandles
contiene elementi duplicati.
Il numero di oggetti in waitHandles
è maggiore di quello consentito dal sistema.
-oppure-
L'attributo STAThreadAttribute viene applicato alla routine del thread corrente e waitHandles
contiene più di un elemento.
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.
timeout
è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.
-oppure-
timeout
è maggiore di Int32.MaxValue.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
La matrice waitHandles
contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala quando viene completata. Il thread principale attende che tutti gli elementi segnalino e quindi esce.
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
Commenti
Se timeout
è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.
Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.
Il WaitAll metodo restituisce quando termina l'attesa, ovvero vengono segnalate tutte le handle o si verifica un timeout. Se vengono passati più di 64 handle, viene generata un'eccezione NotSupportedException . Se la matrice contiene duplicati, la chiamata avrà esito negativo.
Il valore massimo per timeout
è Int32.MaxValue.
Uscita dal contesto
Il exitContext
parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.
Quando il codice viene eseguito in un contesto non predefinito, se true
si specifica per exitContext
fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.
L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true
per exitContext
, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando termina, il thread che ha eseguito la chiamata deve attendere di immettere nuovamente il dominio di sincronizzazione.
Si applica a
WaitAll(WaitHandle[], Int32, Boolean)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.
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
Parametri
- waitHandles
- WaitHandle[]
Matrice WaitHandle
contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto (duplicati).
- millisecondsTimeout
- Int32
Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.
- exitContext
- Boolean
true
per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false
.
Restituisce
true
se ogni elemento in waitHandles
ha ricevuto un segnale; in caso contrario, false
.
Eccezioni
Il valore del parametro waitHandles
è null
.
-oppure-
Uno o più oggetti nella matrice waitHandles
sono null
.
-oppure-
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.
La matrice waitHandles
contiene elementi duplicati.
Il numero di oggetti in waitHandles
è maggiore di quello consentito dal sistema.
-oppure-
Il thread corrente è nello stato STA e waitHandles
contiene più di un elemento.
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.
millisecondsTimeout
è un numero negativo diverso da -1, che rappresenta un timeout infinito.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
La matrice waitHandles
contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala quando viene completata. Il thread principale attende che tutti gli elementi segnalino e quindi esce.
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
Commenti
Se millisecondsTimeout
è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.
Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.
Il WaitAll metodo restituisce quando termina l'attesa, ovvero quando vengono segnalate tutte le handle o quando si verifica il timeout. Se vengono passati più di 64 handle, viene generata un'eccezione NotSupportedException . Se nella matrice sono presenti duplicati, la chiamata ha esito negativo con .DuplicateWaitObjectException
Uscita dal contesto
Il exitContext
parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.
Quando il codice viene eseguito in un contesto non predefinito, se true
si specifica per exitContext
fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.
L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true
per exitContext
, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando questo metodo restituisce, il thread che ha effettuato la chiamata deve attendere di tornare al dominio di sincronizzazione.
Si applica a
WaitAll(WaitHandle[], TimeSpan)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.
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
Parametri
- waitHandles
- WaitHandle[]
Matrice WaitHandle
contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.
- timeout
- TimeSpan
Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.
Restituisce
true
se ogni elemento in waitHandles
ha ricevuto un segnale; in caso contrario, false
.
Eccezioni
Il valore del parametro waitHandles
è null
.
-oppure-
Uno o più oggetti nella matrice waitHandles
sono null
.
-oppure-
waitHandles
è una matrice senza elementi.
La matrice waitHandles
contiene elementi duplicati.
Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.
Il numero di oggetti in waitHandles
è maggiore di quello consentito dal sistema.
-oppure-
Il thread corrente è nello stato STA e waitHandles
contiene più di un elemento.
timeout
è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.
-oppure-
timeout
è maggiore di Int32.MaxValue.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
La matrice waitHandles
contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.
Commenti
Se timeout
è zero, il metodo non blocca. Verifica lo stato degli handle di attesa e restituisce immediatamente.
Il WaitAll metodo restituisce quando termina l'attesa, ovvero tutti gli handle vengono segnalati o si verifica un timeout. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se la matrice contiene duplicati, la chiamata avrà esito negativo.
Il valore massimo per timeout
è Int32.MaxValue.
La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitAll(WaitHandle[], TimeSpan, Boolean) e specificare false
per exitContext
.
Si applica a
WaitAll(WaitHandle[], Int32)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo.
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
Parametri
- waitHandles
- WaitHandle[]
Matrice WaitHandle
contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto (duplicati).
- millisecondsTimeout
- Int32
Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.
Restituisce
true
se ogni elemento in waitHandles
ha ricevuto un segnale; in caso contrario, false
.
Eccezioni
Il valore del parametro waitHandles
è null
.
-oppure-
Uno o più oggetti nella matrice waitHandles
sono null
.
-oppure-
waitHandles
è una matrice senza elementi.
La matrice waitHandles
contiene elementi duplicati.
Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.
Il numero di oggetti in waitHandles
è maggiore di quello consentito dal sistema.
-oppure-
Il thread corrente è nello stato STA e waitHandles
contiene più di un elemento.
millisecondsTimeout
è un numero negativo diverso da -1, che rappresenta un timeout infinito.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
La matrice waitHandles
contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.
Commenti
Se millisecondsTimeout
è zero, il metodo non blocca. Verifica lo stato degli handle di attesa e restituisce immediatamente.
Il WaitAll metodo restituisce quando termina l'attesa, ovvero quando vengono segnalati tutti gli handle o quando si verifica il timeout. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se nella matrice sono presenti duplicati, la chiamata ha esito negativo con un DuplicateWaitObjectExceptionoggetto .
La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitAll(WaitHandle[], Int32, Boolean) e specificare false
per exitContext
.
Si applica a
WaitAll(WaitHandle[])
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Attende che tutti gli elementi nella matrice specificata ricevano un segnale.
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
Parametri
- waitHandles
- WaitHandle[]
Matrice WaitHandle
contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.
Restituisce
true
se ogni elemento in waitHandles
ha ricevuto un segnale; in caso contrario, il metodo non restituisce alcun risultato.
Eccezioni
Il valore del parametro waitHandles
è null
. -oppure-
Uno o più oggetti nella matrice waitHandles
sono null
.
-oppure-
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.
La matrice waitHandles
contiene elementi duplicati.
Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.
Il numero di oggetti in waitHandles
è maggiore di quello consentito dal sistema.
-oppure-
Il thread corrente è nello stato STA e waitHandles
contiene più di un elemento.
waitHandles
è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
La matrice waitHandles
contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala al termine. Il thread principale attende che tutti gli elementi segnalino e quindi esci.
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
Commenti
AbandonedMutexException è nuovo in .NET Framework versione 2.0. Nelle versioni precedenti, il WaitAll metodo restituisce true
quando viene abbandonato un mutex. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.
Il WaitAll metodo restituisce quando vengono segnalati tutti gli handle. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se la matrice contiene duplicati, la chiamata ha esito negativo con un DuplicateWaitObjectExceptionoggetto .
La chiamata all'overload di questo metodo equivale a chiamare l'overload del WaitAll(WaitHandle[], Int32, Boolean) metodo e specificare -1 (o Timeout.Infinite) per millisecondsTimeout
e true
per exitContext
.