WaitHandle.WaitAll Método

Definición

Espera a que todos los elementos de la matriz especificada reciban una señal.

Sobrecargas

WaitAll(WaitHandle[], TimeSpan, Boolean)

Espera a que todos los elementos de la matriz especificada reciban una señal; usa un valor TimeSpan para determinar el intervalo de tiempo y especifica si se va a salir del dominio de sincronización antes de finalizar la espera.

WaitAll(WaitHandle[], Int32, Boolean)

Espera a que todos los elementos de la matriz especificada reciban una señal; usa un valor Int32 para determinar el intervalo de tiempo y especifica si se va a salir del dominio de sincronización antes de finalizar la espera.

WaitAll(WaitHandle[], TimeSpan)

Espera a que todos los elementos de la matriz especificada reciban una señal, usando un valor TimeSpan para especificar el intervalo de tiempo.

WaitAll(WaitHandle[], Int32)

Espera a que todos los elementos de la matriz especificada reciban una señal mediante un valor Int32 para especificar el intervalo de tiempo.

WaitAll(WaitHandle[])

Espera a que todos los elementos de la matriz especificada reciban una señal.

WaitAll(WaitHandle[], TimeSpan, Boolean)

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

Espera a que todos los elementos de la matriz especificada reciban una señal; usa un valor TimeSpan para determinar el intervalo de tiempo y especifica si se va a salir del dominio de sincronización antes de finalizar la espera.

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

Parámetros

waitHandles
WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará. Esta matriz no puede contener varias referencias al mismo objeto.

timeout
TimeSpan

TimeSpan que representa el número de milisegundos de espera o TimeSpan que representa -1 milisegundos para esperar indefinidamente.

exitContext
Boolean

true para salir del dominio de sincronización del contexto antes de la espera (en caso de encontrarse en un contexto sincronizado) y volver a adquirirlo más tarde; de lo contrario, false.

Devoluciones

Es true cuando todos los elementos de waitHandles han recibido una señal; en caso contrario es false.

Excepciones

El parámetro waitHandles es null.

o bien

Uno o varios objetos de la matriz waitHandles son null.

o bien

waitHandles es una matriz sin elementos y la versión de .NET Framework es 2.0 o posterior.

La matriz waitHandles contiene elementos que son duplicados.

El número de objetos de waitHandles es mayor de lo que permite el sistema.

o bien

El atributo STAThreadAttribute se aplica al procedimiento de subproceso para el subproceso actual, y waitHandles contiene más de un elemento.

waitHandles es una matriz sin elementos y la versión de .NET Framework es 1.0 o 1.1.

timeout es un número negativo distinto de -1 milisegundos, que representa un tiempo de espera infinito.

O bien

timeout es mayor que Int32.MaxValue.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La matriz waitHandles contiene un proxy transparente para un WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar el grupo de subprocesos para crear y escribir de forma asincrónica en un grupo de archivos. Cada operación de escritura se pone en cola como un elemento de trabajo y señala cuando finaliza. El subproceso principal espera a que todos los elementos señalen y, a continuación, salga.

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

Comentarios

Si timeout es cero, el método no se bloquea. Comprueba el estado de los identificadores de espera y devuelve inmediatamente.

Si se abandona una exclusión mutua, se produce una AbandonedMutexException excepción . Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El WaitAll método devuelve cuando finaliza la espera, lo que significa que se señalizan todos los identificadores o se produce un tiempo de espera. Si se pasan más de 64 identificadores, se produce una NotSupportedException excepción . Si la matriz contiene duplicados, se producirá un error en la llamada.

Nota

El WaitAll método no se admite en subprocesos en STA estado.

El valor máximo de timeout es Int32.MaxValue.

Salir del contexto

El exitContext parámetro no tiene ningún efecto a menos que se llame a este método desde dentro de un contexto administrado no predeterminado. El contexto administrado puede ser no predeterminado si el subproceso está dentro de una llamada a una instancia de una clase derivada de ContextBoundObject. Incluso si actualmente está ejecutando un método en una clase que no se deriva de ContextBoundObject, como String, puede estar en un contexto no predeterminado si ContextBoundObject está en la pila en el dominio de aplicación actual.

Cuando el código se ejecuta en un contexto no predeterminado, al especificar true para exitContext que el subproceso salga del contexto administrado no predeterminado (es decir, para realizar la transición al contexto predeterminado) antes de ejecutar este método. El subproceso vuelve al contexto no predeterminado original una vez completada la llamada a este método.

Salir del contexto puede ser útil cuando la clase enlazada al contexto tiene el SynchronizationAttribute atributo . En ese caso, todas las llamadas a los miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código de la clase. Si el código de la pila de llamadas de un miembro llama a este método y especifica para exitContext, el subproceso true sale del dominio de sincronización, lo que permite que un subproceso bloqueado en una llamada a cualquier miembro del objeto continúe. Cuando este método vuelve, el subproceso que realizó la llamada debe esperar a volver a escribir el dominio de sincronización.

Se aplica a

WaitAll(WaitHandle[], Int32, Boolean)

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

Espera a que todos los elementos de la matriz especificada reciban una señal; usa un valor Int32 para determinar el intervalo de tiempo y especifica si se va a salir del dominio de sincronización antes de finalizar la espera.

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

Parámetros

waitHandles
WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará. Esta matriz no puede contener varias referencias al mismo objeto (duplicados).

millisecondsTimeout
Int32

Número de milisegundos de espera o Infinite (-1) para esperar indefinidamente.

exitContext
Boolean

true para salir del dominio de sincronización del contexto antes de la espera (en caso de encontrarse en un contexto sincronizado) y volver a adquirirlo más tarde; de lo contrario, false.

Devoluciones

true cuando todos los elementos de waitHandles reciben una señal; en caso contrario, false.

Excepciones

El parámetro waitHandles es null.

o bien

Uno o varios objetos de la matriz waitHandles son null.

o bien

waitHandles es una matriz sin elementos y la versión de .NET Framework es 2.0 o posterior.

La matriz waitHandles contiene elementos que son duplicados.

El número de objetos de waitHandles es mayor de lo que permite el sistema.

o bien

El subproceso actual tiene el estado STA y waitHandles contiene más de un elemento.

waitHandles es una matriz sin elementos y la versión de .NET Framework es 1.0 o 1.1.

millisecondsTimeout es un número negativo distinto de-1, que representa un tiempo de espera infinito.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La matriz waitHandles contiene un proxy transparente para un WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar el grupo de subprocesos para crear y escribir de forma asincrónica en un grupo de archivos. Cada operación de escritura se pone en cola como un elemento de trabajo y señala cuando finaliza. El subproceso principal espera a que todos los elementos señalen y, a continuación, salga.

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

Comentarios

Si millisecondsTimeout es cero, el método no se bloquea. Comprueba el estado de los identificadores de espera y devuelve inmediatamente.

Si se abandona una exclusión mutua, se produce una AbandonedMutexException excepción . Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El WaitAll método devuelve cuando finaliza la espera, lo que significa cuando se señalizan todos los identificadores o cuando se produce el tiempo de espera. Si se pasan más de 64 identificadores, se produce una NotSupportedException excepción . Si hay duplicados en la matriz, se produce un error en la llamada con .DuplicateWaitObjectException

Nota

El WaitAll método no se admite en subprocesos en STA estado.

Salir del contexto

El exitContext parámetro no tiene ningún efecto a menos que se llame a este método desde dentro de un contexto administrado no predeterminado. El contexto administrado puede ser no predeterminado si el subproceso está dentro de una llamada a una instancia de una clase derivada de ContextBoundObject. Incluso si actualmente está ejecutando un método en una clase que no se deriva de ContextBoundObject, como String, puede estar en un contexto no predeterminado si ContextBoundObject está en la pila en el dominio de aplicación actual.

Cuando el código se ejecuta en un contexto no predeterminado, al especificar true para exitContext que el subproceso salga del contexto administrado no predeterminado (es decir, para realizar la transición al contexto predeterminado) antes de ejecutar este método. El subproceso vuelve al contexto no predeterminado original una vez completada la llamada a este método.

Salir del contexto puede ser útil cuando la clase enlazada al contexto tiene el SynchronizationAttribute atributo . En ese caso, todas las llamadas a los miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código de la clase. Si el código de la pila de llamadas de un miembro llama a este método y especifica para exitContext, el subproceso true sale del dominio de sincronización, lo que permite que un subproceso bloqueado en una llamada a cualquier miembro del objeto continúe. Cuando este método vuelve, el subproceso que realizó la llamada debe esperar a volver a escribir el dominio de sincronización.

Se aplica a

WaitAll(WaitHandle[], TimeSpan)

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

Espera a que todos los elementos de la matriz especificada reciban una señal, usando un valor TimeSpan para especificar el intervalo de tiempo.

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

Parámetros

waitHandles
WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará. Esta matriz no puede contener varias referencias al mismo objeto.

timeout
TimeSpan

TimeSpan que representa el número de milisegundos de espera o TimeSpan que representa -1 milisegundos para esperar indefinidamente.

Devoluciones

true cuando todos los elementos de waitHandles reciben una señal; en caso contrario, false.

Excepciones

El parámetro waitHandles es null.

o bien

Uno o varios objetos de la matriz waitHandles son null.

o bien

waitHandles es una matriz sin elementos.

La matriz waitHandles contiene elementos que son duplicados.

Nota: En las aplicaciones .NET para la Tienda Windows o la Biblioteca de clases portable, capture en su lugar la excepción de clase base, ArgumentException.

El número de objetos de waitHandles es mayor de lo que permite el sistema.

o bien

El subproceso actual tiene el estado STA y waitHandles contiene más de un elemento.

timeout es un número negativo distinto de -1 milisegundos, que representa un tiempo de espera infinito.

O bien

timeout es mayor que Int32.MaxValue.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La matriz waitHandles contiene un proxy transparente para un WaitHandle en otro dominio de aplicación.

Comentarios

Si timeout es cero, el método no se bloquea. Comprueba el estado de los identificadores de espera y devuelve inmediatamente.

El WaitAll método devuelve cuando finaliza la espera, lo que significa que se señalizan todos los identificadores o se produce un tiempo de espera. Si se pasan más de 64 identificadores, se produce una NotSupportedException excepción . Si la matriz contiene duplicados, se producirá un error en la llamada.

Nota

El WaitAll método no se admite en subprocesos en STA estado .

El valor máximo de timeout es Int32.MaxValue.

Llamar a esta sobrecarga de método es la misma que llamar a la WaitAll(WaitHandle[], TimeSpan, Boolean) sobrecarga y especificar false para exitContext.

Se aplica a

WaitAll(WaitHandle[], Int32)

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

Espera a que todos los elementos de la matriz especificada reciban una señal mediante un valor Int32 para especificar el intervalo de tiempo.

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

Parámetros

waitHandles
WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará. Esta matriz no puede contener varias referencias al mismo objeto (duplicados).

millisecondsTimeout
Int32

Número de milisegundos de espera o Infinite (-1) para esperar indefinidamente.

Devoluciones

true cuando todos los elementos de waitHandles reciben una señal; en caso contrario, false.

Excepciones

El parámetro waitHandles es null.

o bien

Uno o varios objetos de la matriz waitHandles son null.

o bien

waitHandles es una matriz sin elementos.

La matriz waitHandles contiene elementos que son duplicados.

Nota: En las aplicaciones .NET para la Tienda Windows o la Biblioteca de clases portable, capture en su lugar la excepción de clase base, ArgumentException.

El número de objetos de waitHandles es mayor de lo que permite el sistema.

o bien

El subproceso actual tiene el estado STA y waitHandles contiene más de un elemento.

millisecondsTimeout es un número negativo distinto de-1, que representa un tiempo de espera infinito.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La matriz waitHandles contiene un proxy transparente para un WaitHandle en otro dominio de aplicación.

Comentarios

Si millisecondsTimeout es cero, el método no se bloquea. Comprueba el estado de los identificadores de espera y devuelve inmediatamente.

El WaitAll método devuelve cuando finaliza la espera, lo que significa cuando se señalizan todos los identificadores o cuando se produce el tiempo de espera. Si se pasan más de 64 identificadores, se produce una NotSupportedException excepción . Si hay duplicados en la matriz, se produce un error en la llamada con .DuplicateWaitObjectException

Nota

El WaitAll método no se admite en subprocesos en STA estado .

Llamar a esta sobrecarga de método es la misma que llamar a la WaitAll(WaitHandle[], Int32, Boolean) sobrecarga y especificar false para exitContext.

Se aplica a

WaitAll(WaitHandle[])

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

Espera a que todos los elementos de la matriz especificada reciban una señal.

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

Parámetros

waitHandles
WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará. Esta matriz no puede contener varias referencias al mismo objeto.

Devoluciones

true cuando todos los elementos de waitHandles reciben una señal; en caso contrario, el método nunca devuelve ningún valor.

Excepciones

El parámetro waitHandles es null. o bien

Uno o varios objetos de la matriz waitHandles son null.

o bien

waitHandles es una matriz sin elementos y la versión de .NET Framework es 2.0 o posterior.

La matriz waitHandles contiene elementos que son duplicados.

Nota: En las aplicaciones .NET para la Tienda Windows o la Biblioteca de clases portable, capture en su lugar la excepción de clase base, ArgumentException.

El número de objetos de waitHandles es mayor de lo que permite el sistema.

o bien

El subproceso actual tiene el estado STA y waitHandles contiene más de un elemento.

waitHandles es una matriz sin elementos y la versión de .NET Framework es 1.0 o 1.1.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La matriz waitHandles contiene un proxy transparente para un WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar el grupo de subprocesos para crear y escribir de forma asincrónica en un grupo de archivos. Cada operación de escritura se pone en cola como un elemento de trabajo y indica cuándo finaliza. El subproceso principal espera a que todos los elementos señalen y, a continuación, se cierran.

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

Comentarios

AbandonedMutexException es nuevo en .NET Framework versión 2.0. En versiones anteriores, el WaitAll método devuelve true cuando se abandona una exclusión mutua. Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El WaitAll método devuelve cuando se señalizan todos los identificadores. Si se pasan más de 64 identificadores, se produce una NotSupportedException excepción . Si la matriz contiene duplicados, se produce un DuplicateWaitObjectExceptionerror en la llamada a .

Nota

El WaitAll método no se admite en subprocesos en STA estado .

Llamar a esta sobrecarga de método equivale a llamar a la sobrecarga del WaitAll(WaitHandle[], Int32, Boolean) método y especificar -1 (o Timeout.Infinite) para y true para millisecondsTimeoutexitContext.

Se aplica a