Wenn Sie über ein Ereignis in einer Klasse sprechen, für die Sie Zugriff auf die Quelle haben, können Sie den Guard in die Ereignisdefinition einfügen.
private bool _eventHasSubscribers = false;
private EventHandler<MyDelegateType> _myEvent;
public event EventHandler<MyDelegateType> MyEvent
{
add
{
if (_myEvent == null)
{
_myEvent += value;
}
}
remove
{
_myEvent -= value;
}
}
Das würde sicherstellen, dass nur ein Abonnent das Ereignis für diese Instanz der Klasse abonnieren kann, die das Ereignis bereitstellt.
EDIT siehe Kommentare darüber, warum der oben genannte Code eine schlechte Idee und nicht Thread sicher ist.
Wenn Ihr Problem darin besteht, dass eine einzelne Instanz des Clients mehr als einmal abonniert wird (und Sie mehrere Abonnenten benötigen), muss der Client-Code damit umgehen. So ersetzen
nicht bereits
mit einem Bool Mitglied der Client-Klasse gezeichnet, die festgelegt wird, wenn Sie für die Veranstaltung zum ersten Mal abonnieren.
Edit (nach akzeptiert): Basierend auf den Kommentar von @Glen T (der Einreicher der Frage) den Code für die akzeptierte Lösung, die er mit ging in der Client-Klasse:
if (alreadySubscribedFlag)
{
member.Event += new MemeberClass.Delegate(handler);
}
Wo alreadySubscribedFlag ist eine Membervariable in der Clientklasse, die die erste Subskription für das spezifische Ereignis verfolgt. Leute, die hier das erste Code-Snippet betrachten, beachten Sie bitte @ Runes Kommentar - es ist keine gute Idee, das Verhalten des Abonnierens eines Ereignisses auf nicht naheliegende Weise zu ändern.
EDIT 31/7/2009: Bitte beachten Sie die Kommentare von @Sam Saffron. Wie ich bereits gesagt habe und Sam stimmt zu, dass die erste hier vorgestellte Methode keine sinnvolle Möglichkeit ist, das Verhalten des Ereignis-Abonnements zu modifizieren. Die Konsumenten der Klasse müssen über ihre interne Implementierung Bescheid wissen, um ihr Verhalten zu verstehen. Nicht sehr nett.
@Sam Saffron kommentiert auch die Sicherheit von Fäden. Ich nehme an, dass er sich auf die mögliche Race Condition bezieht, bei der zwei Abonnenten (in der Nähe von) gleichzeitig versuchen, sich zu abonnieren, und sie beide am Ende abonnieren können. Eine Sperre könnte verwendet werden, um dies zu verbessern. Wenn Sie beabsichtigen, die Art und Weise zu ändern, wie das Ereignis-Abonnement funktioniert, rate ich Ihnen, dass Sie read about how to make the subscription add/remove properties thread safe.
Ich denke, ich werde mit der Boolean Member Variable Ansatz weitermachen. Allerdings bin ich ein wenig überrascht, dass es keine andere Möglichkeit gibt zu überprüfen, ob ein Client bereits abonniert ist. Ich hätte gedacht, dass es für einen bestimmten Kunden eher üblich ist, nur einmal zu abonnieren? –
Abhängig von Ihrer Konfiguration möchten Sie möglicherweise eine Ausnahme auslösen, wenn das Ereignis bereits einen Abonnenten hat. Wenn Sie Abonnenten zur Laufzeit hinzufügen, werden sie über den Fehler informiert, anstatt nichts zu tun. Das Ändern des Standardverhaltens ohne Benachrichtigung des Benutzers ist nicht die beste Vorgehensweise. –
Dies ist nicht sicher für Multithreading. –