So stellen Sie sicher, dass ein Ereignis nur einmal abonniert wird
Möchte ich sicherstellen, dass ich nur abonnieren, der einmal in einer bestimmten Klasse für ein Ereignis an eine Instanz.
Z.B. ich möchte in der Lage sein, Folgendes zu tun:
if (*not already subscribed*)
{
member.Event += new MemeberClass.Delegate(handler);
}
Wie würde ich mich über die Durchführung einer solchen Wache?
InformationsquelleAutor der Frage Glen T | 2008-12-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie sprechen über ein Ereignis in einer Klasse, haben Sie Zugriff auf die Quelle, denn dann konnten Sie die Wache in der event-definition.
Die dafür sorgen würde, dass nur ein Teilnehmer kann das Ereignis abonnieren, auf diese Instanz der Klasse, bietet der event.
BEARBEITEN sehen bitte Anmerkungen darüber, warum der obige code ist eine schlechte Idee, und nicht thread-sicher.
Wenn Ihr problem ist, dass eine einzelne Instanz der client abonniert mehr als einmal (und du brauchst mehrere Abonnenten), dann der client-code ist gehen zu müssen, damit umzugehen. So ersetzen Sie
mit einer bool-member der client-Klasse, die festgelegt wird, wenn Sie sich für die Veranstaltung das erste mal.
Bearbeiten (nach akzeptiert): Basiert auf den Kommentar von @Glen T (der Einsender der Frage) den code für die akzeptierte Lösung, ging er mit in der client-Klasse:
Wo alreadySubscribedFlag ist eine member-variable in der client-Klasse, die tracks erste Abonnement, um die jeweilige Veranstaltung.
Menschen, die sich auf das erste code-snippet hier, beachten Sie bitte die @Rune des Kommentar - es ist nicht eine gute Idee, um das Verhalten der Anmeldung zu einer Veranstaltung in eine nicht-offensichtliche Weise.
BEARBEITEN 31/7/2009: siehe Kommentare von @Sam Safran. Wie ich bereits erwähnt, und Sam stimmt die erste hier Vorgestellte Verfahren ist nicht auf eine vernünftige Art und Weise zu ändern, die das Verhalten der Ereignis-Abonnement. Die Verbraucher der Klasse wissen müssen, über Ihre interne Implementierung zu verstehen sein Verhalten. Nicht sehr nett.
@Sam Safran auch Kommentare um die thread-Sicherheit. Ich nehme an, er bezieht sich auf die mögliche race-condition, wo zwei Abonnenten (in der Nähe) gleichzeitig versuchen zu abonnieren, und Sie können beide enden abonnieren. Eine Sperre kann verwendet werden, um diese zu verbessern. Wenn Sie planen, ändern Sie die Art und Weise Ereignis-Abonnement funktioniert, dann rate ich, dass Sie Lesen Sie, wie machen Sie das Abonnement hinzufügen/entfernen von Eigenschaften, die thread-sicher.
InformationsquelleAutor der Antwort Hamish Smith
Ich bin das hinzufügen dieser in alle doppelten Fragen, nur für den Datensatz. Dieses Muster war für mich:
Beachten Sie, dass dies jedes mal, wenn Sie registrieren Sie Ihren handler wird sichergestellt, dass der handler nur einmal registriert wird.
InformationsquelleAutor der Antwort alf
Als andere gezeigt haben, die Sie außer Kraft setzen können, hinzufügen/entfernen von Eigenschaften des Ereignisses. Alternativ können Sie wollen, Graben Sie die Veranstaltung und haben einfach die Klasse nehmen Sie einen Delegaten als argument im Konstruktor (oder einer anderen Methode), und statt das auslösen des Ereignisses rufen Sie das mitgelieferte delegieren.
Ereignisse implizieren, dass jeder abonnieren kann, in der Erwägung, dass ein Delegat ist eine Methode übergeben Sie an die Klasse. Wird wohl weniger überraschend für die Benutzer der Bibliothek dann, wenn Sie nur Ereignisse verwenden, wenn Sie tatsächlich wnat die one-to-many-Semantik, es bietet in der Regel.
InformationsquelleAutor der Antwort jalf
U verwenden können, Postsharper zu schreiben, ein Attribut nur einmal und verwenden Sie es auf normale Ereignisse. Den code wiederverwenden. Code-Beispiel ist unten gegeben.
Nur es so zu benutzen.
Für details schauen Implementieren Postsharp EventInterceptionAspect um zu verhindern, dass ein event-Handler eingehängt zweimal
InformationsquelleAutor der Antwort Saghar
Würden Sie entweder speichern müssen eine separate Markierung, die angibt, ob oder nicht Sie würden abonniert haben oder, wenn Sie haben die Kontrolle über MemberClass, bieten Implementierungen von add-und remove-Methoden für die Veranstaltung:
Entscheiden, ob oder nicht die handler Hinzugefügt wurde, müssen Sie vergleichen die Delegierten kehrten aus GetInvocationList() auf beiden _event und Wert.
InformationsquelleAutor der Antwort Andrew Kennan
Es scheint mir, wie eine einfache Möglichkeit, dies zu tun ist, zu kündigen, Ihre handler (die im hintergrund fehl, wenn Sie nicht abonniert) und dann abonnieren.
Es hat platzieren Sie die Belastung auf die Entwickler, das ist der falsche Weg, es zu tun, aber für die quick-and-dirty das ist quick and dirty.
InformationsquelleAutor der Antwort Scott Baker