Frage

in einem digitalen Signalerfassungssystem, werden häufig Daten in einen Beobachter in dem System durch ein Gewinde geschoben.

Beispiel von Wikipedia / Observer_pattern :

foreach (IObserver observer in observers)
    observer.Update(message);

Wenn z.B. eine Benutzeraktion von z.B. ein GUI-Thread die Daten erfordert fließen zu stoppen, Sie alltogether die fach Beobachter Verbindung und sogar entsorgen Sie den Beobachter brechen wollen.

kann man argumentieren: Sie sollten nur die Datenquelle stoppen, und warten Sie auf einen Sentinel-Wert der Verbindung zu entsorgen. Aber das würde mehr Latenz im System entstehen.

Natürlich, wenn die Daten Pump Thread ist nur für die Adresse des Betrachters gefragt, es könnte es finden Sie eine Nachricht an einem zerstörten Objekt gesendet wird.

Hat jemand erstellt ein ‚offizielles‘ Design Muster begegnet diese Situation? Sollten sie nicht?

War es hilfreich?

Lösung

Wenn Sie die Datenquelle haben wollen auf der sicheren Seite der Parallelität zu immer sein, sollten Sie mindestens einen Zeiger haben, die immer sicher ist für ihn zu verwenden. So ist das Observer-Objekt soll eine Lebensdauer hat, die nicht vor, dass die Datenquelle beendet wird.

Dies kann nur durch das Hinzufügen Beobachter getan werden, aber das Entfernen sie nie. Sie könnten jeden Beobachter haben den Kern Implementierung selbst nicht tun, aber haben sie diese Aufgabe an einen ObserverImpl Objekt delegieren. Sie sperren den Zugang zu diesem Objekt impl. Das ist keine große Sache, es bedeutet nur die GUI unsubscriber für eine kleine Weile blockieren, falls würde der Beobachter ist damit beschäftigt, das ObserverImpl Objekt. Wenn GUI Ansprechbarkeit würde ein Problem sein, können Sie irgendeine Art von gleichzeitigem Job-Queue-Mechanismus mit einem Abmelde Job Aufschieben auf sie verwenden. (Wie in Windows Postmessage)

Wenn abzumelden, ersetzen Sie einfach den Kern Implementierung für eine Dummy-Implementierung. Wiederum sollte dieser Vorgang die Verriegelung greifen. Dies würde in der Tat einige warten auf die Datenquelle vorstellen, aber da es nur eine [lock - Zeiger Swap - Unlock]. Könnte man sagen, dass dies für Echtzeit-Anwendungen schnell genug ist,

Wenn Sie Observer Objekte Stapel vermeiden wollen, dass nur ein Dummy enthalten, haben Sie irgendeine Art von Buchhaltung zu tun, aber dies könnte einkochen zu etwas trivial wie ein Objekt einen Zeiger auf das Observer-Objekt hält er aus der Liste muss.

Optimierung: Wenn Sie halten auch die Implementierungen (die echten + der Dummy) am Leben, so lange wie der Beobachter selbst, können Sie dies ohne eine tatsächliche Sperre tun, und so etwas wie InterlockedExchangePointer verwenden, um die Zeiger zu tauschen. Worst-Case-Szenario: Delegieren Anruf geht auf, während der Zeiger getauscht wird -> keine große Sache alle Objekte am Leben bleiben und delegieren fortsetzen können. Weiter delegierenden Anruf wird zu neuem Implementierungsobjekt sein. (Vorbehaltlich neue Swaps natürlich)

Andere Tipps

Sie können eine Mitteilung an alle Beobachter schicken sie die Datenquelle informiert wird beendet, und lassen Sie die Beobachter selbst aus der Liste entfernen.

Als Reaktion auf den Kommentar, die Umsetzung des Themas-Beobachter-Muster für dynamische Hinzufügen / Entfernen von Beobachtern ermöglichen soll. In C # ist das Ereignissystem ein Thema / Beobachter-Muster, wo Beobachter verwenden event += observer hinzugefügt und mit event -= observer entfernt.

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