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)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Boolean

Paramètres

waitHandles
WaitHandle[]

Tableau WaitHandle qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.

timeout
TimeSpan

TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.

exitContext
Boolean

true pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false.

Retours

true lorsque tous les éléments de waitHandles ont reçu un signal ; sinon, false.

Exceptions

Le paramètre waitHandles a la valeur null.

- ou -

Un ou plusieurs des objets dans le tableau waitHandles sont null.

- ou -

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.

Le tableau waitHandles contient des éléments qui sont des doublons.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.

- ou -

L’attribut STAThreadAttribute est appliqué à la procédure de thread pour le thread actuel, et waitHandles contient plusieurs éléments.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.

timeout est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.

-ou-

timeout est supérieur à Int32.MaxValue.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.

using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;

// Maintain state to pass to WriteToFile.
ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}

};

ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}


public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }

   }

};

int main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
   State^ stateInfo;
   if (  !Directory::Exists( dirName ) )
   {
      Directory::CreateDirectory( dirName );
   }

   
   // Queue the work items that create and write to the files.
   for ( int i = 0; i < numberOfFiles; i++ )
   {
      fileName = String::Concat( dirName,  "\\Test", ((i)).ToString(),  ".dat" );
      
      // Create random data to write to the file.
      byteArray = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );

   }
   
   // Since ThreadPool threads are background threads, 
   // wait for the work items to signal before exiting.
   if ( WaitHandle::WaitAll( manualEvents, TimeSpan(0,0,5), false ) )
   {
      Console::WriteLine( "Files written - main exiting." );
   }
   else
   {
      
      // The wait operation times out.
      Console::WriteLine( "Error writing files - main exiting." );
   }
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        if(WaitHandle.WaitAll(
            manualEvents, new TimeSpan(0, 0, 5), false))
        {
            Console.WriteLine("Files written - main exiting.");
        }
        else
        {
            // The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.");
        }
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            fileName = String.Concat( _
                dirName, "\Test", i.ToString(), ".dat")

            ' Create random data to write to the file.
            byteArray = New Byte(1000000){}
            randomGenerator.NextBytes(byteArray)

            manualEvents(i) = New ManualResetEvent(false)

            stateInfo = _ 
                New State(fileName, byteArray, manualEvents(i))

            ThreadPool.QueueUserWorkItem(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' Since ThreadPool threads are background threads, 
        ' wait for the work items to signal before exiting.
        If WaitHandle.WaitAll( _
            manualEvents, New TimeSpan(0, 0, 5), false) = True  Then

            Console.WriteLine("Files written - main exiting.")
        Else
        
            ' The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.")
        End If
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

Remarques

Si timeout a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.

Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou qu’un délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.

Notes

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

La valeur maximale pour timeout est Int32.MaxValue.

Sortie du contexte

Le exitContext paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non défini par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à une instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non défini par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non défini par défaut, la spécification true de pour exitContext entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.

Quitter le contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés, et le domaine de synchronisation est le corps entier du code de la classe. Si le code dans la pile des appels d’un membre appelle cette méthode et spécifie true pour exitContext, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre pour revenir dans le domaine de synchronisation.

S’applique à

WaitAll(WaitHandle[], Int32, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * int * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Boolean

Paramètres

waitHandles
WaitHandle[]

Tableau WaitHandle qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).

millisecondsTimeout
Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.

exitContext
Boolean

true pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.

Exceptions

Le paramètre waitHandles a la valeur null.

- ou -

Un ou plusieurs des objets dans le tableau waitHandles sont null.

- ou -

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.

Le tableau waitHandles contient des éléments qui sont des doublons.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.

- ou -

Le thread actuel est à l’état STA, et waitHandles contient plusieurs éléments.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.

using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;

// Maintain state to pass to WriteToFile.
ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}

};

ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}


public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }

   }

};

int main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
   State^ stateInfo;
   if (  !Directory::Exists( dirName ) )
   {
      Directory::CreateDirectory( dirName );
   }

   
   // Queue the work items that create and write to the files.
   for ( int i = 0; i < numberOfFiles; i++ )
   {
      fileName = String::Concat( dirName,  "\\Test", ((i)).ToString(),  ".dat" );
      
      // Create random data to write to the file.
      byteArray = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );

   }
   
   // Since ThreadPool threads are background threads, 
   // wait for the work items to signal before exiting.
   if ( WaitHandle::WaitAll( manualEvents, 5000, false ) )
   {
      Console::WriteLine( "Files written - main exiting." );
   }
   else
   {
      
      // The wait operation times out.
      Console::WriteLine( "Error writing files - main exiting." );
   }
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        if(WaitHandle.WaitAll(manualEvents, 5000, false))
        {
            Console.WriteLine("Files written - main exiting.");
        }
        else
        {
            // The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.");
        }
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            fileName = String.Concat( _
                dirName, "\Test", i.ToString(), ".dat")

            ' Create random data to write to the file.
            byteArray = New Byte(1000000){}
            randomGenerator.NextBytes(byteArray)

            manualEvents(i) = New ManualResetEvent(false)

            stateInfo = _ 
                New State(fileName, byteArray, manualEvents(i))

            ThreadPool.QueueUserWorkItem(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' Since ThreadPool threads are background threads, 
        ' wait for the work items to signal before exiting.
        If WaitHandle.WaitAll(manualEvents, 5000, false) = True  Then

            Console.WriteLine("Files written - main exiting.")
        Else
        
            ' The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.")
        End If
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

Remarques

Si millisecondsTimeout a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.

Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou lorsque le délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. S’il existe des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException.

Notes

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

Sortie du contexte

Le exitContext paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non défini par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à une instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non défini par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non défini par défaut, la spécification true de pour exitContext entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.

Quitter le contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés, et le domaine de synchronisation est le corps entier du code de la classe. Si le code dans la pile des appels d’un membre appelle cette méthode et spécifie true pour exitContext, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre pour revenir dans le domaine de synchronisation.

S’applique à

WaitAll(WaitHandle[], TimeSpan)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan) As Boolean

Paramètres

waitHandles
WaitHandle[]

Tableau WaitHandle qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.

timeout
TimeSpan

TimeSpan qui représente le nombre de millisecondes à attendre ou TimeSpan qui représente -1 milliseconde, pour attendre indéfiniment.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.

Exceptions

Le paramètre waitHandles a la valeur null.

- ou -

Un ou plusieurs des objets dans le tableau waitHandles sont null.

- ou -

waitHandles est un tableau sans éléments.

Le tableau waitHandles contient des éléments qui sont des doublons.

Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.

- ou -

Le thread actuel est à l’état STA, et waitHandles contient plusieurs éléments.

timeout est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.

-ou-

timeout est supérieur à Int32.MaxValue.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.

Remarques

Si timeout a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou qu’un délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. Si le tableau contient des doublons, l’appel échoue.

Notes

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

La valeur maximale pour timeout est Int32.MaxValue.

L’appel de cette surcharge de méthode revient à appeler la WaitAll(WaitHandle[], TimeSpan, Boolean) surcharge et à spécifier false pour exitContext.

S’applique à

WaitAll(WaitHandle[], Int32)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAll : System.Threading.WaitHandle[] * int -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Boolean

Paramètres

waitHandles
WaitHandle[]

Tableau WaitHandle qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet (doublons).

millisecondsTimeout
Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, false.

Exceptions

Le paramètre waitHandles a la valeur null.

- ou -

Un ou plusieurs des objets dans le tableau waitHandles sont null.

- ou -

waitHandles est un tableau sans éléments.

Le tableau waitHandles contient des éléments qui sont des doublons.

Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.

- ou -

Le thread actuel est à l’état STA, et waitHandles contient plusieurs éléments.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.

Remarques

Si millisecondsTimeout a la valeur zéro, la méthode ne se bloque pas. Il teste l’état des handles d’attente et retourne immédiatement.

La WaitAll méthode retourne lorsque l’attente se termine, ce qui signifie que tous les handles sont signalés ou lorsque le délai d’attente se produit. Si plus de 64 poignées sont passées, une NotSupportedException est levée. S’il existe des doublons dans le tableau, l’appel échoue avec un DuplicateWaitObjectException.

Notes

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

L’appel de cette surcharge de méthode revient à appeler la WaitAll(WaitHandle[], Int32, Boolean) surcharge et à spécifier false pour exitContext.

S’applique à

WaitAll(WaitHandle[])

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Attend que tous les éléments du tableau spécifié reçoivent un signal.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);
static member WaitAll : System.Threading.WaitHandle[] -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle()) As Boolean

Paramètres

waitHandles
WaitHandle[]

Tableau WaitHandle qui contient les objets que l'instance actuelle attendra. Ce tableau ne peut pas contenir plusieurs références au même objet.

Retours

true quand tous les éléments de waitHandles ont reçu un signal ; sinon, la méthode ne retourne jamais.

Exceptions

Le paramètre waitHandles a la valeur null. - ou -

Un ou plusieurs des objets dans le tableau waitHandles sont null.

- ou -

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 2.0 ou ultérieure.

Le tableau waitHandles contient des éléments qui sont des doublons.

Remarque : Dans .NET pour les applications du Windows Store ou la Bibliothèque de classes portable, interceptez plutôt l’exception de la classe de base ArgumentException.

Le nombre d’objets dans waitHandles est supérieur à ce que le système autorise.

- ou -

Le thread actuel est à l’état STA, et waitHandles contient plusieurs éléments.

waitHandles est un tableau sans éléments, et que la version de .NET Framework est 1.0 ou 1.1.

L’attente a été arrêtée, car un thread s’est terminé sans libérer de mutex.

Le tableau waitHandles contient un proxy transparent pour un WaitHandle dans un autre domaine d’application.

Exemples

L’exemple de code suivant montre comment utiliser le pool de threads pour créer et écrire de manière asynchrone dans un groupe de fichiers. Chaque opération d’écriture est mise en file d’attente en tant qu’élément de travail et signale quand elle est terminée. Le thread principal attend que tous les éléments signalent, puis se ferme.

using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;

ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}

};

ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}


public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }

   }

};

void main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
   State^ stateInfo;
   if (  !Directory::Exists( dirName ) )
   {
      Directory::CreateDirectory( dirName );
   }

   
   // Queue the work items that create and write to the files.
   for ( int i = 0; i < numberOfFiles; i++ )
   {
      fileName = String::Concat( dirName,  "\\Test", ((i)).ToString(),  ".dat" );
      
      // Create random data to write to the file.
      byteArray = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );

   }
   
   // Since ThreadPool threads are background threads, 
   // wait for the work items to signal before exiting.
   WaitHandle::WaitAll( manualEvents );
   Console::WriteLine( "Files written - main exiting." );
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        WaitHandle.WaitAll(manualEvents);
        Console.WriteLine("Files written - main exiting.");
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            fileName = String.Concat( _
                dirName, "\Test", i.ToString(), ".dat")

            ' Create random data to write to the file.
            byteArray = New Byte(1000000){}
            randomGenerator.NextBytes(byteArray)

            manualEvents(i) = New ManualResetEvent(false)

            stateInfo = _ 
                New State(fileName, byteArray, manualEvents(i))

            ThreadPool.QueueUserWorkItem(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' Since ThreadPool threads are background threads, 
        ' wait for the work items to signal before exiting.
        WaitHandle.WaitAll(manualEvents)
        Console.WriteLine("Files written - main exiting.")
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

Remarques

AbandonedMutexException est nouveau dans .NET Framework version 2.0. Dans les versions précédentes, la WaitAll méthode retourne true quand un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

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

Notes

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

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

S’applique à