WaitHandle.WaitAll Méthode
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Attend que tous les éléments du tableau spécifié reçoivent un signal.
Surcharges
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente. |
WaitAll(WaitHandle[], Int32, Boolean) |
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente. |
WaitAll(WaitHandle[], TimeSpan) |
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps. |
WaitAll(WaitHandle[], Int32) |
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps. |
WaitAll(WaitHandle[]) |
Attend que tous les éléments du tableau spécifié reçoivent un signal. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.
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
Paramètres
- waitHandles
- WaitHandle[]
Tableau WaitHandle
qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.
- timeout
- TimeSpan
TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.
- exitContext
- Boolean
true
pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false
.
Retours
true
lorsque tous les éléments de waitHandles
ont reçu un signal ; sinon, false
.
Exceptions
Le paramètre waitHandles
a la valeur null
.
- ou -
Un ou plusieurs des objets dans le tableau waitHandles
sont null
.
- ou -
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.
Le tableau waitHandles
contient des éléments qui sont des doublons.
Le nombre d’objets dans waitHandles
est supérieur à ce que le système autorise.
- ou -
L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles
contient plusieurs éléments.
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.
timeout
est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.
-ou-
timeout
est supérieur à Int32.MaxValue.
L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.
Le tableau waitHandles
contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.
Exemples
L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.
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
Remarques
Si timeout
a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.
Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.
La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou qu’un délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.
La valeur maximale pour timeout
est Int32.MaxValue.
Sortie du contexte
Le exitContext
paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non défini par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à une instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non défini par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.
Lorsque votre code s’exécute dans un contexte non défini par défaut, la spécification true
de pour exitContext
entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.
Quitter le contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés, et le domaine de synchronisation est le corps entier du code de la classe. Si le code dans la pile des appels d’un membre appelle cette méthode et spécifie true
pour exitContext
, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre pour revenir dans le domaine de synchronisation.
S’applique à
WaitAll(WaitHandle[], Int32, Boolean)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.
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
Paramètres
- waitHandles
- WaitHandle[]
Tableau WaitHandle
qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).
- millisecondsTimeout
- Int32
Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.
- exitContext
- Boolean
true
pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false
.
Retours
true
quand tous les éléments de waitHandles
ont reçu un signal ; sinon, false
.
Exceptions
Le paramètre waitHandles
a la valeur null
.
- ou -
Un ou plusieurs des objets dans le tableau waitHandles
sont null
.
- ou -
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.
Le tableau waitHandles
contient des éléments qui sont des doublons.
Le nombre d’objets dans waitHandles
est supérieur à ce que le système autorise.
- ou -
Le thread actuel est à l’état STA, et waitHandles
contient plusieurs éléments.
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.
millisecondsTimeout
est un nombre négatif différent de -1, qui représente un délai d’attente infini.
L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.
Le tableau waitHandles
contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.
Exemples
L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.
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
Remarques
Si millisecondsTimeout
a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.
Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.
La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou lorsque le délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. S’il existe des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException.
Sortie du contexte
Le exitContext
paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non défini par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à une instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non défini par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.
Lorsque votre code s’exécute dans un contexte non défini par défaut, la spécification true
de pour exitContext
entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.
Quitter le contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés, et le domaine de synchronisation est le corps entier du code de la classe. Si le code dans la pile des appels d’un membre appelle cette méthode et spécifie true
pour exitContext
, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre pour revenir dans le domaine de synchronisation.
S’applique à
WaitAll(WaitHandle[], TimeSpan)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.
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
Paramètres
- waitHandles
- WaitHandle[]
Tableau WaitHandle
qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.
- timeout
- TimeSpan
TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.
Retours
true
quand tous les éléments de waitHandles
ont reçu un signal ; sinon, false
.
Exceptions
Le paramètre waitHandles
a la valeur null
.
- ou -
Un ou plusieurs des objets dans le tableau waitHandles
sont null
.
- ou -
waitHandles
est un tableau sans éléments.
Le tableau waitHandles
contient des éléments qui sont des doublons.
Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.
Le nombre d’objets dans waitHandles
est supérieur à ce que le système autorise.
- ou -
Le thread actuel est à l’état STA, et waitHandles
contient plusieurs éléments.
timeout
est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.
-ou-
timeout
est supérieur à Int32.MaxValue.
L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.
Le tableau waitHandles
contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.
Remarques
Si timeout
a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.
La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou qu’un délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.
La valeur maximale pour timeout
est Int32.MaxValue.
L’appel de cette surcharge de méthode revient à appeler la WaitAll(WaitHandle[], TimeSpan, Boolean) surcharge et à spécifier false
pour exitContext
.
S’applique à
WaitAll(WaitHandle[], Int32)
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps.
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
Paramètres
- waitHandles
- WaitHandle[]
Tableau WaitHandle
qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).
- millisecondsTimeout
- Int32
Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.
Retours
true
quand tous les éléments de waitHandles
ont reçu un signal ; sinon, false
.
Exceptions
Le paramètre waitHandles
a la valeur null
.
- ou -
Un ou plusieurs des objets dans le tableau waitHandles
sont null
.
- ou -
waitHandles
est un tableau sans éléments.
Le tableau waitHandles
contient des éléments qui sont des doublons.
Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.
Le nombre d’objets dans waitHandles
est supérieur à ce que le système autorise.
- ou -
Le thread actuel est à l’état STA, et waitHandles
contient plusieurs éléments.
millisecondsTimeout
est un nombre négatif différent de -1, qui représente un délai d’attente infini.
L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.
Le tableau waitHandles
contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.
Remarques
Si millisecondsTimeout
a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.
La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou lorsque le délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. S’il existe des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException.
L’appel de cette surcharge de méthode revient à appeler la WaitAll(WaitHandle[], Int32, Boolean) surcharge et à spécifier false
pour exitContext
.
S’applique à
WaitAll(WaitHandle[])
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
- Source:
- WaitHandle.cs
Attend que tous les éléments du tableau spécifié reçoivent un signal.
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
Paramètres
- waitHandles
- WaitHandle[]
Tableau WaitHandle
qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.
Retours
true
quand tous les éléments de waitHandles
ont reçu un signal ; sinon, la méthode ne retourne jamais.
Exceptions
Le paramètre waitHandles
a la valeur null
. - ou -
Un ou plusieurs des objets dans le tableau waitHandles
sont null
.
- ou -
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.
Le tableau waitHandles
contient des éléments qui sont des doublons.
Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.
Le nombre d’objets dans waitHandles
est supérieur à ce que le système autorise.
- ou -
Le thread actuel est à l’état STA, et waitHandles
contient plusieurs éléments.
waitHandles
est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.
L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.
Le tableau waitHandles
contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.
Exemples
L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.
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
Remarques
AbandonedMutexException est nouveau dans .NET Framework version 2.0. Dans les versions précédentes, la WaitAll méthode retourne true
quand un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.
La WaitAll méthode retourne lorsque tous les handles sont signalés. Si plus de 64 poignées sont passées, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue avec un DuplicateWaitObjectException.
Appeler cette surcharge de méthode revient à appeler la surcharge de méthode WaitAll(WaitHandle[], Int32, Boolean) et à spécifier -1 (ou Timeout.Infinite) pour millisecondsTimeout
et true
pour exitContext
.