WaitHandle.WaitAll WaitHandle.WaitAll WaitHandle.WaitAll WaitHandle.WaitAll Method

Définition

Attend que tous les éléments du tableau spécifié reçoivent un signal.Waits for all the elements in the specified array to receive a signal.

Surcharges

WaitAll(WaitHandle[], TimeSpan, Boolean) WaitAll(WaitHandle[], TimeSpan, Boolean) WaitAll(WaitHandle[], TimeSpan, Boolean) 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.Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval, and specifying whether to exit the synchronization domain before the wait.

WaitAll(WaitHandle[], Int32, Boolean) WaitAll(WaitHandle[], Int32, Boolean) WaitAll(WaitHandle[], Int32, Boolean) 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.Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitAll(WaitHandle[], TimeSpan) WaitAll(WaitHandle[], TimeSpan) WaitAll(WaitHandle[], TimeSpan) 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.Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval.

WaitAll(WaitHandle[], Int32) WaitAll(WaitHandle[], Int32) WaitAll(WaitHandle[], Int32) 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.Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval.

WaitAll(WaitHandle[]) WaitAll(WaitHandle[]) WaitAll(WaitHandle[]) WaitAll(WaitHandle[])

Attend que tous les éléments du tableau spécifié reçoivent un signal.Waits for all the elements in the specified array to receive a signal.

WaitAll(WaitHandle[], TimeSpan, Boolean) WaitAll(WaitHandle[], TimeSpan, Boolean) WaitAll(WaitHandle[], TimeSpan, Boolean) 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.Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval, and specifying whether to exit the synchronization domain before the wait.

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.A WaitHandle array containing the objects for which the current instance will wait. Ce tableau ne peut pas contenir plusieurs références au même objet.This array cannot contain multiple references to the same object.

timeout
TimeSpan TimeSpan TimeSpan TimeSpan

TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.A TimeSpan that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds, to wait indefinitely.

exitContext
Boolean Boolean Boolean 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.true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

Retours

true lorsque tous les éléments de waitHandles ont reçu un signal ; sinon, false.true when every element in waitHandles has received a signal; otherwise false.

Exceptions

Le paramètre waitHandles a la valeur null.The waitHandles parameter is null.

ou-or- Un ou plusieurs des objets dans le tableau waitHandles sont null.One or more of the objects in the waitHandles array is null.

- ou --or- waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.waitHandles is an array with no elements and the .NET Framework version is 2.0 or later.

Le tableau waitHandles contient des éléments qui sont des doublons.The waitHandles array contains elements that are duplicates.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.The number of objects in waitHandles is greater than the system permits.

- ou --or- L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.The STAThreadAttribute attribute is applied to the thread procedure for the current thread, and waitHandles contains more than one element.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.waitHandles is an array with no elements and the .NET Framework version is 1.0 or 1.1.

timeout est un nombre négatif autre que -1 milliseconde, qui représente un délai d’attente infini.timeout is a negative number other than -1 milliseconds, which represents an infinite time-out. - ou --or- timeout est supérieur à MaxValue.timeout is greater than MaxValue.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.The wait terminated because a thread exited without releasing a mutex. Cette exception n’est pas levée sur Windows 98 ou Windows Millennium Edition.This exception is not thrown on Windows 98 or Windows Millennium Edition.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.The waitHandles array contains a transparent proxy for a WaitHandle in another application domain.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de façon asynchrone dans un groupe de fichiers.The following code example shows how to use the thread pool to asynchronously create and write to a group of files. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale lorsqu’elle est terminée.Each write operation is queued as a work item and signals when it is finished. Le thread principal attend que tous les éléments signalent, puis se ferme.The main thread waits for all the items to signal and then exits.

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
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 est égal à zéro, la méthode n’est pas bloquée.If timeout is zero, the method does not block. Il teste l’état des handles d’attente et retourne immédiatement.It tests the state of the wait handles and returns immediately.

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework.AbandonedMutexException is new in the .NET Framework version 2.0. Dans les versions précédentes, WaitAll la méthode true retourne lorsqu’un mutex est abandonné.In previous versions, the WaitAll method returns true when a mutex is abandoned. Un mutex abandonné indique souvent une erreur de codage grave.An abandoned mutex often indicates a serious coding error. Dans le cas d’un mutex à l’ensemble du système, cela peut indiquer qu’une application a été interrompue brusquement (par exemple, à l’aide du gestionnaire des tâches Windows).In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). L’exception contient des informations utiles pour le débogage.The exception contains information useful for debugging.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les descripteurs sont signalés ou qu’un délai d’attente est dépassé.The WaitAll method returns when the wait terminates, which means either all the handles are signaled or a time-out occurs. Dans certaines implémentations, si plus de 64 handles sont passés, NotSupportedException une est levée.On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. Si le tableau contient des doublons, l’appel échoue.If the array contains duplicates, the call will fail.

Notes

La WaitAll méthode n’est pas prise en charge sur STAThreadAttributeles threads qui ont.The WaitAll method is not supported on threads that have STAThreadAttribute.

La valeur maximale pour timeout est Int32.MaxValue.The maximum value for timeout is Int32.MaxValue.

Remarques sur la sortie du contexteNotes on Exiting the Context

Le exitContext paramètre n’a aucun effet, WaitAll à moins que la méthode ne soit appelée à partir d’un contexte managé non défini par défaut.The exitContext parameter has no effect unless the WaitAll method is called from inside a nondefault managed context. Cela peut se produire si votre thread est à l’intérieur d’un appel à une instance d' ContextBoundObjectune classe dérivée de.This can happen if your thread is inside a call to an instance of a class derived from 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 ContextBoundObject si un est sur votre pile dans le domaine d’application actuel.Even if you are currently executing a method on a class that is not derived from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

Lorsque votre code s’exécute dans un contexte non défini par défaut, true la exitContext spécification de pour oblige le thread à quitter le contexte managé non défini par défaut (c’est-à-dire à passer au contexte par défaut) avant WaitAll d’exécuter la méthode.When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitAll method. Elle retourne au contexte par défaut d’origine une fois l’appel à WaitAll la méthode terminé.It returns to the original nondefault context after the call to the WaitAll method completes.

Cela peut être utile lorsque la classe liée au contexte a SynchronizationAttribute.This can be useful when the context-bound class has 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 pour la classe.In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. Si le code de la pile des appels d’un membre WaitAll appelle la méthode true et exitContextspécifie pour, 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.If code in the call stack of a member calls the WaitAll method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. Lorsque la WaitAll méthode est retournée, le thread qui a effectué l’appel doit attendre pour entrer de nouveau dans le domaine de synchronisation.When the WaitAll method returns, the thread that made the call must wait to reenter the synchronization domain.

WaitAll(WaitHandle[], Int32, Boolean) WaitAll(WaitHandle[], Int32, Boolean) WaitAll(WaitHandle[], Int32, Boolean) 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.Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval and specifying whether to exit the synchronization domain before the wait.

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.A WaitHandle array containing the objects for which the current instance will wait. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).This array cannot contain multiple references to the same object (duplicates).

millisecondsTimeout
Int32 Int32 Int32 Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.The number of milliseconds to wait, or Infinite (-1) to wait indefinitely.

exitContext
Boolean Boolean Boolean 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.true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.true when every element in waitHandles has received a signal; otherwise, false.

Exceptions

Le paramètre waitHandles a la valeur null.The waitHandles parameter is null.

ou-or- Un ou plusieurs des objets dans le tableau waitHandles sont null.One or more of the objects in the waitHandles array is null.

- ou --or- waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.waitHandles is an array with no elements and the .NET Framework version is 2.0 or later.

Le tableau waitHandles contient des éléments qui sont des doublons.The waitHandles array contains elements that are duplicates.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.The number of objects in waitHandles is greater than the system permits.

- ou --or- L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.The STAThreadAttribute attribute is applied to the thread procedure for the current thread, and waitHandles contains more than one element.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.waitHandles is an array with no elements and the .NET Framework version is 1.0 or 1.1.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.millisecondsTimeout is a negative number other than -1, which represents an infinite time-out.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.The wait completed because a thread exited without releasing a mutex. Cette exception n’est pas levée sur Windows 98 ou Windows Millennium Edition.This exception is not thrown on Windows 98 or Windows Millennium Edition.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.The waitHandles array contains a transparent proxy for a WaitHandle in another application domain.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de façon asynchrone dans un groupe de fichiers.The following code example shows how to use the thread pool to asynchronously create and write to a group of files. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale lorsqu’elle est terminée.Each write operation is queued as a work item and signals when it is finished. Le thread principal attend que tous les éléments signalent, puis se ferme.The main thread waits for all the items to signal and then exits.

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
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 est égal à zéro, la méthode n’est pas bloquée.If millisecondsTimeout is zero, the method does not block. Il teste l’état des handles d’attente et retourne immédiatement.It tests the state of the wait handles and returns immediately.

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework.AbandonedMutexException is new in the .NET Framework version 2.0. Dans les versions précédentes, WaitAll la méthode true retourne lorsqu’un mutex est abandonné.In previous versions, the WaitAll method returns true when a mutex is abandoned. Un mutex abandonné indique souvent une erreur de codage grave.An abandoned mutex often indicates a serious coding error. Dans le cas d’un mutex à l’ensemble du système, cela peut indiquer qu’une application a été interrompue brusquement (par exemple, à l’aide du gestionnaire des tâches Windows).In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). L’exception contient des informations utiles pour le débogage.The exception contains information useful for debugging.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que lorsque tous les descripteurs sont signalés ou lorsque le délai d’attente est dépassé.The WaitAll method returns when the wait terminates, which means either when all the handles are signaled or when time-out occurs. Dans certaines implémentations, si plus de 64 handles sont passés, NotSupportedException une est levée.On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. S’il y a des doublons dans le tableau, l’appel échoue DuplicateWaitObjectExceptionavec un.If there are duplicates in the array, the call fails with a DuplicateWaitObjectException.

Notes

La WaitAll méthode n’est pas prise en charge sur STAThreadAttributeles threads qui ont.The WaitAll method is not supported on threads that have STAThreadAttribute.

Remarques sur la sortie du contexteNotes on Exiting the Context

Le exitContext paramètre n’a aucun effet, WaitAll à moins que la méthode ne soit appelée à partir d’un contexte managé non défini par défaut.The exitContext parameter has no effect unless the WaitAll method is called from inside a nondefault managed context. Cela peut se produire si votre thread est à l’intérieur d’un appel à une instance d' ContextBoundObjectune classe dérivée de.This can happen if your thread is inside a call to an instance of a class derived from 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 ContextBoundObject si un est sur votre pile dans le domaine d’application actuel.Even if you are currently executing a method on a class that is not derived from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

Lorsque votre code s’exécute dans un contexte non défini par défaut, true la exitContext spécification de pour oblige le thread à quitter le contexte managé non défini par défaut (c’est-à-dire à passer au contexte par défaut) avant WaitAll d’exécuter la méthode.When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitAll method. Le thread retourne au contexte par défaut d’origine une fois l’appel à WaitAll la méthode terminé.The thread returns to the original nondefault context after the call to the WaitAll method completes.

Cela peut être utile lorsque la classe liée au contexte a l' SynchronizationAttribute attribut.This can be useful when the context-bound class has the SynchronizationAttribute attribute. 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 pour la classe.In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. Si le code de la pile des appels d’un membre WaitAll appelle la méthode true et exitContextspécifie pour, 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.If code in the call stack of a member calls the WaitAll method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. Lorsque la WaitAll méthode est retournée, le thread qui a effectué l’appel doit attendre pour entrer de nouveau dans le domaine de synchronisation.When the WaitAll method returns, the thread that made the call must wait to reenter the synchronization domain.

WaitAll(WaitHandle[], TimeSpan) WaitAll(WaitHandle[], TimeSpan) WaitAll(WaitHandle[], TimeSpan) 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.Waits for all the elements in the specified array to receive a signal, using a TimeSpan value to specify the time interval.

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.A WaitHandle array containing the objects for which the current instance will wait. Ce tableau ne peut pas contenir plusieurs références au même objet.This array cannot contain multiple references to the same object.

timeout
TimeSpan TimeSpan TimeSpan TimeSpan

TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.A TimeSpan that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds, to wait indefinitely.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.true when every element in waitHandles has received a signal; otherwise, false.

Exceptions

Le paramètre waitHandles a la valeur null.The waitHandles parameter is null.

- ou --or- Un ou plusieurs des objets dans le tableau waitHandles sont null.One or more of the objects in the waitHandles array is null.

- ou --or- waitHandles est un tableau sans éléments.waitHandles is an array with no elements.

Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez l’exception de la classe de base, ArgumentException, à la place.In the .NET for Windows Store apps or the Portable Class Library, catch the base class exception, ArgumentException, instead.

Le tableau waitHandles contient des éléments qui sont des doublons.The waitHandles array contains elements that are duplicates.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.The number of objects in waitHandles is greater than the system permits.

- ou --or- L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.The STAThreadAttribute attribute is applied to the thread procedure for the current thread, and waitHandles contains more than one element.

timeout est un nombre négatif autre que -1 milliseconde, qui représente un délai d’attente infini.timeout is a negative number other than -1 milliseconds, which represents an infinite time-out. - ou --or- timeout est supérieur à MaxValue.timeout is greater than MaxValue.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.The wait terminated because a thread exited without releasing a mutex. Cette exception n’est pas levée sur Windows 98 ou Windows Millennium Edition.This exception is not thrown on Windows 98 or Windows Millennium Edition.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.The waitHandles array contains a transparent proxy for a WaitHandle in another application domain.

Remarques

Si timeout est égal à zéro, la méthode n’est pas bloquée.If timeout is zero, the method does not block. Il teste l’état des handles d’attente et retourne immédiatement.It tests the state of the wait handles and returns immediately.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les descripteurs sont signalés ou qu’un délai d’attente est dépassé.The WaitAll method returns when the wait terminates, which means either all the handles are signaled or a time-out occurs. Dans certaines implémentations, si plus de 64 handles sont passés, NotSupportedException une est levée.On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. Si le tableau contient des doublons, l’appel échoue.If the array contains duplicates, the call will fail.

Notes

La WaitAll méthode n’est pas prise en charge sur STAThreadAttributeles threads qui ont.The WaitAll method is not supported on threads that have STAThreadAttribute.

La valeur maximale pour timeout est Int32.MaxValue.The maximum value for timeout is Int32.MaxValue.

L’appel de cette surcharge de méthode est identique à WaitAll(WaitHandle[], TimeSpan, Boolean) l’appel de false la exitContextsurcharge et à la spécification de pour.Calling this method overload is the same as calling the WaitAll(WaitHandle[], TimeSpan, Boolean) overload and specifying false for exitContext.

WaitAll(WaitHandle[], Int32) WaitAll(WaitHandle[], Int32) WaitAll(WaitHandle[], Int32) 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.Waits for all the elements in the specified array to receive a signal, using an Int32 value to specify the time interval.

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.A WaitHandle array containing the objects for which the current instance will wait. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).This array cannot contain multiple references to the same object (duplicates).

millisecondsTimeout
Int32 Int32 Int32 Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.The number of milliseconds to wait, or Infinite (-1) to wait indefinitely.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.true when every element in waitHandles has received a signal; otherwise, false.

Exceptions

Le paramètre waitHandles a la valeur null.The waitHandles parameter is null.

ou-or- Un ou plusieurs des objets dans le tableau waitHandles sont null.One or more of the objects in the waitHandles array is null.

- ou --or- waitHandles est un tableau sans éléments.waitHandles is an array with no elements.

Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez l’exception de la classe de base, ArgumentException, à la place.In the .NET for Windows Store apps or the Portable Class Library, catch the base class exception, ArgumentException, instead.

Le tableau waitHandles contient des éléments qui sont des doublons.The waitHandles array contains elements that are duplicates.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.The number of objects in waitHandles is greater than the system permits.

ou-or- L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.The STAThreadAttribute attribute is applied to the thread procedure for the current thread, and waitHandles contains more than one element.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.millisecondsTimeout is a negative number other than -1, which represents an infinite time-out.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.The wait completed because a thread exited without releasing a mutex. Cette exception n’est pas levée sur Windows 98 ou Windows Millennium Edition.This exception is not thrown on Windows 98 or Windows Millennium Edition.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.The waitHandles array contains a transparent proxy for a WaitHandle in another application domain.

Remarques

Si millisecondsTimeout est égal à zéro, la méthode n’est pas bloquée.If millisecondsTimeout is zero, the method does not block. Il teste l’état des handles d’attente et retourne immédiatement.It tests the state of the wait handles and returns immediately.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que lorsque tous les descripteurs sont signalés ou lorsque le délai d’attente est dépassé.The WaitAll method returns when the wait terminates, which means either when all the handles are signaled or when time-out occurs. Dans certaines implémentations, si plus de 64 handles sont passés, NotSupportedException une est levée.On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. S’il y a des doublons dans le tableau, l’appel échoue DuplicateWaitObjectExceptionavec un.If there are duplicates in the array, the call fails with a DuplicateWaitObjectException.

Notes

La WaitAll méthode n’est pas prise en charge sur STAThreadAttributeles threads qui ont.The WaitAll method is not supported on threads that have STAThreadAttribute.

L’appel de cette surcharge de méthode est identique à WaitAll(WaitHandle[], Int32, Boolean) l’appel de false la exitContextsurcharge et à la spécification de pour.Calling this method overload is the same as calling the WaitAll(WaitHandle[], Int32, Boolean) overload and specifying false for exitContext.

WaitAll(WaitHandle[]) WaitAll(WaitHandle[]) WaitAll(WaitHandle[]) WaitAll(WaitHandle[])

Attend que tous les éléments du tableau spécifié reçoivent un signal.Waits for all the elements in the specified array to receive a 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.A WaitHandle array containing the objects for which the current instance will wait. Ce tableau ne peut pas contenir plusieurs références au même objet.This array cannot contain multiple references to the same object.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, la méthode ne retourne jamais.true when every element in waitHandles has received a signal; otherwise the method never returns.

Exceptions

Le paramètre waitHandles a la valeur null.The waitHandles parameter is null. - ou --or- Un ou plusieurs des objets dans le tableau waitHandles sont null.One or more of the objects in the waitHandles array are null.

- ou --or- waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.waitHandles is an array with no elements and the .NET Framework version is 2.0 or later.

Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez l’exception de la classe de base, ArgumentException, à la place.In the .NET for Windows Store apps or the Portable Class Library, catch the base class exception, ArgumentException, instead.

Le tableau waitHandles contient des éléments qui sont des doublons.The waitHandles array contains elements that are duplicates.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.The number of objects in waitHandles is greater than the system permits.

- ou --or- L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.The STAThreadAttribute attribute is applied to the thread procedure for the current thread, and waitHandles contains more than one element.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.waitHandles is an array with no elements and the .NET Framework version is 1.0 or 1.1.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.The wait terminated because a thread exited without releasing a mutex. Cette exception n’est pas levée sur Windows 98 ou Windows Millennium Edition.This exception is not thrown on Windows 98 or Windows Millennium Edition.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.The waitHandles array contains a transparent proxy for a WaitHandle in another application domain.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de façon asynchrone dans un groupe de fichiers.The following code example shows how to use the thread pool to asynchronously create and write to a group of files. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale lorsqu’elle est terminée.Each write operation is queued as a work item and signals when it is finished. Le thread principal attend que tous les éléments signalent, puis se ferme.The main thread waits for all the items to signal and then exits.

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
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

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework.AbandonedMutexException is new in the .NET Framework version 2.0. Dans les versions précédentes, WaitAll la méthode true retourne lorsqu’un mutex est abandonné.In previous versions, the WaitAll method returns true when a mutex is abandoned. Un mutex abandonné indique souvent une erreur de codage grave.An abandoned mutex often indicates a serious coding error. Dans le cas d’un mutex à l’ensemble du système, cela peut indiquer qu’une application a été interrompue brusquement (par exemple, à l’aide du gestionnaire des tâches Windows).In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). L’exception contient des informations utiles pour le débogage.The exception contains information useful for debugging.

La WaitAll méthode retourne lorsque tous les descripteurs sont signalés.The WaitAll method returns when all the handles are signaled. Dans certaines implémentations, si plus de 64 handles sont passés, NotSupportedException une est levée.On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. Si le tableau contient des doublons, l’appel échoue avec DuplicateWaitObjectExceptionun.If the array contains duplicates, the call fails with a DuplicateWaitObjectException.

Notes

La WaitAll méthode n’est pas prise en charge sur STAThreadAttributeles threads qui ont.The WaitAll method is not supported on threads that have STAThreadAttribute.

L’appel de cette surcharge de méthode équivaut à WaitAll(WaitHandle[], Int32, Boolean) appeler la surcharge de méthode et à spécifier Timeout.Infinite-1 ( true ou exitContext) pour millisecondsTimeout et pour.Calling this method overload is equivalent to calling the WaitAll(WaitHandle[], Int32, Boolean) method overload and specifying -1 (or Timeout.Infinite) for millisecondsTimeout and true for exitContext.

S’applique à