Frage

Ist die Umsetzung unter Thread-sicher? Wenn nicht, was bin ich dabei? Sollte ich die volatile Keywords irgendwo haben? Oder ein Schloss irgendwo in der OnProcessingCompleted Methode? Wenn ja, wo?

public abstract class ProcessBase : IProcess
{
    private readonly object completedEventLock = new object();

    private event EventHandler<ProcessCompletedEventArgs> ProcessCompleted;

    event EventHandler<ProcessCompletedEventArgs> IProcess.ProcessCompleted
    {
        add
        {
            lock (completedEventLock)
                ProcessCompleted += value;
        }
        remove
        {
            lock (completedEventLock)
                ProcessCompleted -= value;
        }
    }

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
    {
        EventHandler<ProcessCompletedEventArgs> handler = ProcessCompleted;
        if (handler != null)
            handler(this, e);
    }
}

Hinweis: Der Grund, warum ich private Veranstaltung und explizite Schnittstelle Zeug haben, ist, weil es eine abstrakte Basisklasse ist. Und die Klassen, die von ihm erben sollen nicht mit diesem Fall direkt nichts tun. Hinzugefügt Wrapper die Klasse, so dass es klar ist =)

War es hilfreich?

Lösung

Es besteht keine Notwendigkeit für das private ProcessCompleted Mitglied eine event zu sein - es ist nur ein Bereich sein könnte. private EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - innerhalb der Klasse geht es immer gerade auf das Feld, so dass das event Zeug sowieso verloren

Der Ansatz, den Sie mit einem expliziten Sperrobjekt gezeigt haben, ist nicht viel mehr Thread-sicher als nur ein Feld artiges Ereignis (dh public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - der einzige Unterschied ist, dass Sie nicht Sperren "this" (das ist eine gute Sache - sollten Sie ideal vermeiden auf this Verriegelung) .. der "handler Variable" Ansatz ist die richtige, aber es gibt immer noch a href = "http <: //blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx“rel = "nofollow noreferrer"> Nebenwirkungen sollten Sie sich bewusst sein .

Andere Tipps

Sie müssen sperren, wenn Sie den Handler holen, sonst können Sie nicht den neuesten Wert haben:

protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
{
    EventHandler<ProcessCompletedEventArgs> handler;
    lock (completedEventLock) 
    {
        handler = ProcessCompleted;
    }
    if (handler != null)
        handler(this, e);
}

Beachten Sie, dass diese nicht verhindern eine Race-Bedingung, wo wir entschieden haben, werden wir eine Reihe von Behandlungsroutinen und dann ausführen ein Handler unsubscribed. Es wird noch genannt werden, weil wir die Multicastdelegat in die handler Variable geholt haben enthalten.

Es gibt nicht viel Sie dies tun können, außer macht den Handler selbst bewusst, dass es nicht mehr aufgerufen werden soll.

Es ist wohl besser, nur nicht versuchen die Ereignisse Thread-sicher zu machen - angeben, dass das Abonnement sollte nur Änderung des Threads, das Ereignis auslösen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top