2 von 3 fanden dies hilfreich - Dieses Thema bewerten.

AutoResetEvent-Klasse

Benachrichtigt einen wartenden Thread über das Eintreten eines Ereignisses. Diese Klasse kann nicht vererbt werden.

Namespace: System.Threading
Assembly: mscorlib (in 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
HinweisHinweis

Das auf diese Klasse angewendete HostProtectionAttribute-Attribut besitzt den Resources-Eigenschaftenwert Synchronization | ExternalThreading. Das HostProtectionAttribute hat keine Auswirkungen auf Desktopanwendungen (die normalerweise durch Doppelklicken auf ein Symbol, Eingeben eines Befehls oder eines URL in einem Browser gestartet werden). Weitere Informationen finden Sie unter der HostProtectionAttribute-Klasse oder unter SQL Server-Programmierung und Hostschutzattribute.

In .NET Framework, Version 2.0, wird AutoResetEvent von der neuen EventWaitHandle-Klasse abgeleitet. Eine AutoResetEvent-Klasse ist hinsichtlich ihrer Funktion gleichwertig mit einer EventWaitHandle-Klasse, die mit dem EventResetMode.AutoReset-Flag erstellt wird.

HinweisHinweis

Anders als die AutoResetEvent-Klasse ermöglicht die EventWaitHandle-Klasse den Zugriff auf benannte Systemsynchronisierungsereignisse.

Mit AutoResetEvent können Threads untereinander durch Signalisieren kommunizieren. Normalerweise betrifft diese Kommunikation eine Ressource, auf die Threads exklusiv zugreifen müssen.

Ein Thread wartet auf ein Signal, indem er WaitOne in AutoResetEvent aufruft. Wenn sich AutoResetEvent im nicht signalisierten Zustand befindet, wird der Thread blockiert und wartet darauf, dass der die Ressource steuernde Thread die Verfügbarkeit der Ressource durch das Aufrufen von Set signalisiert.

Der Aufruf von Set signalisiert AutoResetEvent, einen wartenden Thread freizugeben. AutoResetEvent verbleibt im signalisierten Zustand, bis ein einzelner wartender Thread freigegeben wird, und wechselt dann automatisch in den nicht signalisierten Zustand zurück. Wenn sich keine Threads in Warteposition befinden, bleibt der signalisierte Zustand auf unbestimmte Zeit erhalten.

Sie können den Anfangszustand eines AutoResetEvent steuern, indem Sie dem Konstruktor einen booleschen Wert übergeben; true, wenn der Anfangszustand signalisiert ist, andernfalls false.

AutoResetEvent kann auch mit der staticWaitAll-Methode und der WaitAny-Methode verwendet werden.

Weitere Informationen zu Mechanismen zur Threadsynchronisierung finden Sie unter AutoResetEvent in der Dokumentation.

Im folgenden Codebeispiel wird die Verwendung von WaitHandles veranschaulicht, um bei einer komplizierten Berechnung eines Zahlenwerts den Abschluss verschiedener Stufen zu signalisieren. Die Berechnung hat folgende Form: result = first term + second term + third term, wobei für jeden Ausdruck eine Vorberechnung und eine Endberechnung mithilfe einer berechneten Basiszahl erforderlich ist.

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

Fanden Sie dies hilfreich?
(1500 verbleibende Zeichen)
Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?