Exportar (0) Imprimir
Expandir todo
Este tema aún no ha recibido ninguna valoración - Valorar este tema

ManualResetEvent (Clase)

Actualización: noviembre 2007

Notifica que se ha producido un evento a uno o varios subprocesos en espera. No se puede heredar esta clase.

Espacio de nombres:  System.Threading
Ensamblado:  mscorlib (en mscorlib.dll)
[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
	ExternalThreading = true)]
public sealed class ManualResetEvent : EventWaitHandle
/** @attribute ComVisibleAttribute(true) */
/** @attribute HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true) */
public final class ManualResetEvent extends EventWaitHandle
public final class ManualResetEvent extends EventWaitHandle
2ssskfws.alert_note(es-es,VS.90).gifNota:

El atributo HostProtectionAttribute aplicado a este tipo o miembro tiene el siguiente valor de la propiedad Resources: Synchronization | ExternalThreading. El atributo HostProtectionAttribute no afecta a las aplicaciones de escritorio (que normalmente se inician haciendo doble clic en un icono, escribiendo un comando o introduciendo una dirección URL en el explorador). Para obtener más información, vea la clase HostProtectionAttribute o Programación de SQL Server y atributos de protección del host.

En la versión 2.0 de .NET Framework, ManualResetEvent deriva de la nueva clase EventWaitHandle. ManualResetEvent es funcionalmente el equivalente a EventWaitHandle creado con EventResetMode.ManualReset.

2ssskfws.alert_note(es-es,VS.90).gifNota:

A diferencia de la clase ManualResetEvent, la clase EventWaitHandle proporciona acceso a los eventos de sincronización del sistema con nombre.

ManualResetEvent permite que los subprocesos se comuniquen entre sí mediante señales. Normalmente, esta comunicación tiene relación con una tarea que un subproceso debe terminar para que puedan continuar otros subprocesos.

Cuando un subproceso comienza una actividad que se debe terminar para que puedan continuar otros subprocesos, llama a Reset para poner ManualResetEvent en el estado de no señalado. Es como si este subproceso controlara a ManualResetEvent. Los subprocesos que llaman a WaitOne en ManualResetEvent se bloquean en espera de la señal. Cuando el subproceso controlador termina la actividad, llama a Set para indicar que los subprocesos en espera pueden continuar. Se liberan todos los subprocesos en espera.

Una vez que se ha señalado, ManualResetEvent permanece señalado hasta que se restablece manualmente. Es decir, las llamadas a WaitOne se devuelven inmediatamente.

El estado inicial de un ManualResetEvent se puede controlar pasando un valor Boolean al constructor, true si se señala el estado inicial y, en caso contrario, false.

ManualResetEvent también se puede utilizar con los métodos staticWaitAll y WaitAny.

Para obtener más información acerca de los mecanismos de sincronización de subprocesos, vea ManualResetEvent en la documentación conceptual.

En el ejemplo de código siguiente se muestra la forma de utilizar indicadores de espera para mostrar la finalización de las distintas fases de un cálculo numérico complicado. El cálculo tiene el formato: resultado = primer término + segundo término + tercer término, donde cada término requiere un cálculo previo y un cálculo final que utiliza un número base calculado.

using System;
using System.Threading;

class CalculateTest
{
    static void Main()
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", 
            calc.Result(234).ToString());
        Console.WriteLine("Result = {0}.", 
            calc.Result(55).ToString());
    }
}

class Calculate
{
    double baseNumber, firstTerm, secondTerm, thirdTerm;
    AutoResetEvent[] autoEvents;
    ManualResetEvent manualEvent;

    // Generate random numbers to simulate the actual calculations.
    Random randomGenerator;

    public Calculate()
    {
        autoEvents = new AutoResetEvent[]
        {
            new AutoResetEvent(false),
            new AutoResetEvent(false),
            new AutoResetEvent(false)
        };

        manualEvent = new ManualResetEvent(false);
    }

    void CalculateBase(object stateInfo)
    {
        baseNumber = randomGenerator.NextDouble();

        // Signal that baseNumber is ready.
        manualEvent.Set();
    }

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.

    void CalculateFirstTerm(object stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator.NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent.WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0].Set();
    }

    void CalculateSecondTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[1].Set();
    }

    void CalculateThirdTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[2].Set();
    }

    public double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateBase));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateFirstTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateSecondTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent.Reset();

        return firstTerm + secondTerm + thirdTerm;
    }
}


import System.*;
import System.Threading.*;

class CalculateTest
{
    public static void main(String[] args)
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(234)));
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(55)));
    } //main
} //CalculateTest

class Calculate
{
    private double baseNumber, firstTerm, secondTerm, thirdTerm;
    private AutoResetEvent autoEvents[];
    private ManualResetEvent manualEvent;

    // Generate random numbers to simulate the actual calculations.
    private Random randomGenerator;

    public Calculate()
    {
        autoEvents = new AutoResetEvent[] { new AutoResetEvent(false), 
            new AutoResetEvent(false), new AutoResetEvent(false) };
        manualEvent = new ManualResetEvent(false);
    } //Calculate

    void CalculateBase(Object stateInfo)
    {
        baseNumber = randomGenerator.NextDouble();

        // Signal that baseNumber is ready.
        manualEvent.Set();
    } //CalculateBase

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.
    void CalculateFirstTerm(Object stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator.NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent.WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * randomGenerator.NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0].Set();
    } //CalculateFirstTerm

    void CalculateSecondTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[1].Set();
    } //CalculateSecondTerm

    void CalculateThirdTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[2].Set();
    } //CalculateThirdTerm

    public double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateBase));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateFirstTerm));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateSecondTerm));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent.Reset();
        return firstTerm + secondTerm + thirdTerm;
    } //Result
} //Calculate


Esta clase es segura para subprocesos.

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile para Smartphone, Windows Mobile para Pocket PC, Xbox 360

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Compatible con: 3.5, 2.0, 1.0

XNA Framework

Compatible con: 2.0, 1.0
¿Te ha resultado útil?
(Caracteres restantes: 1500)
Gracias por sus comentarios

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft. Reservados todos los derechos.