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.WaitAny (WaitHandle[], Int32, Boolean)

 

Publicado: octubre de 2016

Espera a que cualquiera de los elementos de la matriz especificada reciba una señal; utiliza un entero de 32 bits con signo para determinar el intervalo de tiempo y especifica si se va a salir del dominio de sincronización antes de la espera.

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

public static int WaitAny(
	WaitHandle[] waitHandles,
	int millisecondsTimeout,
	bool exitContext
)

Parámetros

waitHandles
Type: System.Threading.WaitHandle[]

Matriz WaitHandle que contiene los objetos por los que la instancia actual esperará.

millisecondsTimeout
Type: System.Int32

Número de milisegundos de espera o Timeout.Infinite (-1) 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.Int32

Índice de matriz del objeto que satisfizo la espera o WaitTimeout si ningún objeto satisfizo la espera y transcurrió un intervalo de tiempo equivalente a millisecondsTimeout.

Exception Condition
ArgumentNullException

El parámetro waitHandles es null.

-o-

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

NotSupportedException

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

ApplicationException

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

ArgumentOutOfRangeException

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

AbandonedMutexException

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

ArgumentException

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

InvalidOperationException

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

Si millisecondsTimeout 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 WaitAny método devuelve true Si la espera finaliza porque 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 WaitAny método produce un AbandonedMutexException sólo cuando la espera finaliza por una exclusión mutua abandonada. Si waitHandles contiene una exclusión mutua liberada con un número inferior de índice de la exclusión mutua abandonada, el WaitAny método se completa con normalidad y no se produce la excepción.

System_CAPS_noteNota

En las versiones de .NET Framework anteriores a la versión 2.0, si un subproceso termina o se interrumpe sin liberar explícitamente un Mutex, y que Mutex está en el índice 0 (cero) en un WaitAny matriz en otro subproceso, el índice devuelto por WaitAny es 128 en lugar de 0.

Este método devuelve cuando finaliza la espera, cuando cualquiera de los identificadores está señalado o cuando se produce un tiempo de espera. Si durante la llamada se señala más de un objeto, el valor devuelto es el índice de matriz del objeto señalado con el menor valor de índice de todos los objetos señalados. En algunas implementaciones, si se pasan 64 identificadores, más de un NotSupportedException se produce.

El exitContext parámetro no tiene ningún efecto a menos que el WaitAny 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 deriva 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 WaitAny método. El subproceso volverá al contexto no predeterminado original después de la llamada a la WaitAny 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 WaitAny (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 WaitAny 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 buscar simultáneamente un archivo en varios discos. Por motivos de espacio, se busca sólo el directorio raíz de cada disco.

using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(autoEvents, 3000, false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}

.NET Framework
Disponible desde 1.1
Volver al principio
Mostrar: