Este artículo se tradujo automáticamente. Para ver el artículo en inglés, active la casilla Inglés. Además, puede mostrar el texto en inglés en una ventana emergente si mueve el puntero del mouse sobre el texto.
Traducción
Inglés

Método WaitHandle.WaitAll (WaitHandle[], TimeSpan, Boolean)

 

Publicado: octubre de 2016

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.

Espacio de nombres:   System.Threading
Ensamblado:  mscorlib (en mscorlib.dll)

public static bool WaitAll(
	WaitHandle[] waitHandles,
	TimeSpan timeout,
	bool exitContext
)

Parámetros

waitHandles
Type: System.Threading.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
Type: System.TimeSpan

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

exitContext
Type: System.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.

Valor devuelto

Type: System.Boolean

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

Exception Condition
ArgumentNullException

El parámetro waitHandles es null.

O bien

Uno o varios de los objetos de la waitHandles matriz es null.

-o-

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

DuplicateWaitObjectException

El waitHandles matriz contiene elementos que son duplicados.

NotSupportedException

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

O bien

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

ApplicationException

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

ArgumentOutOfRangeException

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

-o-

timeout es mayor que Int32.MaxValue.

AbandonedMutexException

La espera finalizó porque un subproceso sale sin liberar una exclusión mutua. Esta excepción no se produce en Windows 98 o Windows Millennium Edition.

InvalidOperationException

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

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

AbandonedMutexException es nuevo en la versión 2.0 de .NET Framework. En versiones anteriores, el WaitAll método devuelve true cuando se abandona una exclusión mutua. A menudo, un mutex abandonado indica un error de codificación grave. En el caso de una exclusión mutua todo el sistema, podría indicar que una aplicación ha finalizado inesperadamente (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 todos los identificadores están señalados o se produce un tiempo de espera. En algunas implementaciones, si se pasan más de 64 identificadores, un NotSupportedException se produce. Si la matriz contiene duplicados, se producirá un error en la llamada.

System_CAPS_noteNota

El WaitAll método no se admite en subprocesos que tienen STAThreadAttribute.

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

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

Cuando el código se ejecuta en un contexto no predeterminado, especificar true para exitContext hace que el subproceso salga del contexto administrado no predeterminado (es decir, que pase al contexto predeterminado) antes de ejecutar el WaitAll método. Se devuelve al contexto no predeterminado original después de la llamada a la WaitAll método se completa.

Esto puede ser útil cuando la clase enlazada de contexto tiene SynchronizationAttribute. En ese caso, todas las llamadas a miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código para la clase. Si el código de la pila de llamadas de un miembro llama el WaitAll (método) y especifica true para exitContext, el subproceso saldrá del dominio de sincronización, que permite que un subproceso que esté bloqueado en una llamada a cualquier miembro del objeto para continuar. Cuando el WaitAll devuelve el método, el subproceso que realiza la llamada debe esperar para volver a escribir el dominio de sincronización.

En el ejemplo de código siguiente se muestra cómo utilizar el grupo de subprocesos para crear y escribir en un grupo de archivos de forma asincrónica. Cuando haya terminado, se pone en cola de cada operación de escritura como un elemento de trabajo y las señales. El subproceso principal espera a que todos los elementos señalar y, a continuación, sale.

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();
        }
    }
}

.NET Framework
Disponible desde 1.1
Volver al principio
Mostrar: