Exportar (0) Imprimir
Expandir todo

AutoResetEvent (Clase)

Notifica que se ha producido un evento a un subproceso en espera. No se puede heredar esta clase.

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

[ComVisibleAttribute(true)] 
public sealed class AutoResetEvent : EventWaitHandle
/** @attribute ComVisibleAttribute(true) */ 
public final class AutoResetEvent extends EventWaitHandle
ComVisibleAttribute(true) 
public final class AutoResetEvent extends EventWaitHandle
No aplicable.

NotaNota:

El atributo HostProtectionAttribute aplicado a esta clase tiene el valor de propiedad Resources siguiente: Synchronization | ExternalThreading. HostProtectionAttribute no afecta a las aplicaciones de escritorio (que normalmente se inician al hacer doble clic en un icono, escribir un comando o escribir una dirección URL en un 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, la clase AutoResetEvent se deriva de la nueva clase EventWaitHandle. Una clase AutoResetEvent es equivalente en lo a funciones se refiere a una clase EventWaitHandle creada con una enumeración EventResetMode.AutoReset.

NotaNota:

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

AutoResetEvent permite que los subprocesos se comuniquen unos con otros mediante señales. Normalmente, esta comunicación tiene relación con un recurso al que los subprocesos necesitan acceso exclusivo.

Un subproceso espera una señal mediante una llamada a WaitOne en el AutoResetEvent. Si AutoResetEvent se encuentra en el estado no señalado, el subproceso se bloquea en espera de que el subproceso que controla el recurso en ese momento indique que dicho recurso está disponible mediante una llamada a Set.

Una llamada a Set indica a AutoResetEvent que libere un subproceso en espera. AutoResetEvent permanece señalado hasta que se libera un único subproceso en espera y, a continuación, vuelve automáticamente al estado de no señalado. Si no hay ningún subproceso en espera, el estado permanece señalado indefinidamente.

NotaImportante:

No hay ninguna garantía de que cada llamada al método Set liberará un subproceso. Si dos llamadas están muy seguidas, de modo que la segunda llamada se produce antes de que se haya liberado un subproceso, sólo se liberará un subproceso. Es como si la segunda llamada no hubiera ocurrido. Además, si se llama a Set cuando no hay subprocesos en espera y ya se ha marcadoAutoResetEvent, la llamada no tendrá ningún efecto.

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

AutoResetEvent puede utilizarse también con los métodos staticWaitAll y WaitAny.

Para obtener más información acerca de los mecanismos de sincronización de subprocesos, vea AutoResetEvent 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 la forma siguiente: result = first term + second term + third term, donde cada término requiere un cálculo previo y un cálculo final utilizando 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 98, Windows 2000 Service Pack 4, Windows CE, Windows Millennium, Windows Mobile para Pocket PC, Windows Mobile para Smartphone, Windows Server 2003, Windows XP Media Center, Windows XP Professional x64, Windows XP SP2, Windows XP Starter

Microsoft .NET Framework 3.0 es compatible con Windows Vista, Microsoft Windows XP SP2 y Windows Server 2003 SP1.

.NET Framework

Compatible con: 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Compatible con: 2.0, 1.0

XNA Framework

Compatible con: 1.0
Mostrar:
© 2015 Microsoft