WaitHandle.WaitAll Méthode

Définition

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)

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

Boolean

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 à 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 façon 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 lorsqu’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 est égal à zéro, la méthode n’est pas bloquée. Il teste l’état des handles d’attente et retourne immédiatement.

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework. Dans les versions précédentes, la WaitAll méthode retourne true lorsqu’un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. 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 de Windows gestionnaire des tâches). 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 descripteurs sont signalés ou qu’un délai d’attente est dépassé. Si plus de 64 handles sont passés, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.

Notes

La WaitAll méthode n’est pas prise en charge sur les threads dans l' STA État.

La valeur maximale pour timeout est Int32.MaxValue .

Remarques sur la sortie du contexte

Le exitContext paramètre n’a aucun effet, à moins que la WaitAll méthode ne soit appelée à partir d’un contexte managé non défini par défaut. Cela peut se produire si votre thread est à 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 est sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non défini par défaut, true la spécification de pour exitContext oblige le thread à quitter le contexte managé non défini par défaut (c’est-à-dire à passer au contexte par défaut) avant d’exécuter la WaitAll méthode. Elle retourne au contexte par défaut d’origine une fois l’appel à la WaitAll méthode terminé.

Cela peut être utile lorsque la classe liée au contexte a 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. Si le code de la pile des appels d’un membre appelle la WaitAll 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 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.

S’applique à

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.

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

Boolean

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 façon 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 lorsqu’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 est égal à zéro, la méthode n’est pas bloquée. Il teste l’état des handles d’attente et retourne immédiatement.

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework. Dans les versions précédentes, la WaitAll méthode retourne true lorsqu’un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. 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 de Windows gestionnaire des tâches). L’exception contient des informations utiles pour le débogage.

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é. Si plus de 64 handles sont passés, une NotSupportedException est levée. S’il y a des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException .

Notes

La WaitAll méthode n’est pas prise en charge sur les threads dans l' STA État.

Remarques sur la sortie du contexte

Le exitContext paramètre n’a aucun effet, à moins que la WaitAll méthode ne soit appelée à partir d’un contexte managé non défini par défaut. Cela peut se produire si votre thread est à 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 est sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non défini par défaut, true la spécification de pour exitContext oblige le thread à quitter le contexte managé non défini par défaut (c’est-à-dire à passer au contexte par défaut) avant d’exécuter la WaitAll méthode. Le thread retourne au contexte par défaut d’origine une fois l’appel à la WaitAll méthode terminé.

Cela peut être utile lorsque la classe liée au contexte a l' SynchronizationAttribute attribut. 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. Si le code de la pile des appels d’un membre appelle la WaitAll 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 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.

S’applique à

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.

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

Boolean

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 à 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 est égal à zéro, la méthode n’est pas bloquée. 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 descripteurs sont signalés ou qu’un délai d’attente est dépassé. Si plus de 64 handles sont passés, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.

Notes

La WaitAll méthode n’est pas prise en charge sur les threads dans l' STA État.

La valeur maximale pour timeout est Int32.MaxValue .

L’appel de cette surcharge de méthode est identique à l’appel WaitAll(WaitHandle[], TimeSpan, Boolean) de la surcharge et à la spécification false de pour exitContext .

S’applique à

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.

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

Boolean

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 est égal à zéro, la méthode n’est pas bloquée. 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 lorsque tous les descripteurs sont signalés ou lorsque le délai d’attente est dépassé. Si plus de 64 handles sont passés, une NotSupportedException est levée. S’il y a des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException .

Notes

La WaitAll méthode n’est pas prise en charge sur les threads dans l' STA État.

L’appel de cette surcharge de méthode est identique à l’appel WaitAll(WaitHandle[], Int32, Boolean) de la surcharge et à la spécification false de pour exitContext .

S’applique à

WaitAll(WaitHandle[])

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

Boolean

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 façon 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 lorsqu’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

AbandonedMutexExceptionest une nouveauté de la version 2,0 de .NET Framework. Dans les versions précédentes, la WaitAll méthode retourne true lorsqu’un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. 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 de Windows gestionnaire des tâches). L’exception contient des informations utiles pour le débogage.

La WaitAll méthode retourne lorsque tous les descripteurs sont signalés. Si plus de 64 handles sont passés, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue avec un DuplicateWaitObjectException .

Notes

La WaitAll méthode n’est pas prise en charge sur les threads dans l' STA État.

L’appel de cette surcharge de méthode équivaut à appeler la WaitAll(WaitHandle[], Int32, Boolean) surcharge de méthode et à spécifier-1 (ou Timeout.Infinite ) pour millisecondsTimeout et true pour exitContext .

S’applique à