2009-05-03 25 views
17

Wie würden Sie die beste Möglichkeit zur Vermeidung doppelter Ereignisabonnements vorschlagen? Wenn diese Codezeile an zwei Stellen ausgeführt wird, wird das Ereignis zweimal ausgeführt. Ich versuche, Ereignisse von Drittanbietern durch zweimaliges Abonnieren zu vermeiden.Vermeiden Sie doppelte Ereignisabonnements in C#

theOBject.TheEvent += RunMyCode; 

In meinem Delegierten Setter, ich kann diese effektiv laufen ...

theOBject.TheEvent -= RunMyCode; 
theOBject.TheEvent += RunMyCode; 

aber ist, dass der beste Weg?

Antwort

19

Ich denke, die effizienteste Art und Weise, ist jede Veranstaltung zu einem Objekt zu machen und Gleichzeitigkeit Sperren, um es hinzuzufügen, wie in diesem Example:

private EventHandler _theEvent; 
private object _eventLock = new object(); 
public event EventHandler TheEvent 
{ 
    add 
    { 
     lock (_eventLock) 
     { 
      _theEvent -= value; 
      _theEvent += value; 
     } 
    } 
    remove 
    { 
     lock (_eventLock) 
     { 
      _theEvent -= value; 
     } 
    } 
} 
+2

Dave Morton hat seine Domain geändert. Die neue URL ist: http://codinglight.blogspot.com/2009/02/preventing-duplicate-subscriptions-to.html –

+0

FYI, wenn Sie eine 503 am Link nur aktualisieren Sie die Seite. Es schien nach ein paar Versuchen für mich zu laden. – Dan

1

Wenn Sie die Quelle für die Klasse von TheObject besitzen, haben Sie Zugriff auf die InvocationList von TheEvent. Sie können einen eigenen Add-Accessor für das Ereignis implementieren und vor dem Hinzufügen überprüfen.

Allerdings denke ich, dass Ihre Vorgehensweise auch in Ordnung ist.

2

Ist Ihr Code Multi-Threaded? Die Gleichzeitigkeitssperre wird nur benötigt, wenn sie multi-threaded ist. Wenn es nicht ein Overhead ist.

Als solche ist Ihre Vorgehensweise zum Abmelden und Abonnieren korrekt.

Danke

0

Ich benutze Ihren Ansatz mit Ausnahme eines Details. Ich denke, dass Ereignisse abonniert werden sollten, wenn Sie eine neue Instanz von Subscriber oder theObject erstellen, dies macht den Code geradliniger. Also, alles, was Sie brauchen, ist nur sorgfältig zu beobachten, nachdem die richtigen Objekte zu entsorgen (Entsorgen Patten ist eine bequeme Lösung dafür).

Sie haben erwähnt, dass Sie ein Ereignis eines Drittanbieters verwenden. Dies bedeutet, dass Sie Ihre eigene Realisierung für Add/Remove-Methoden nicht bereitstellen können, wie Ihnen mitgeteilt wurde. Aber in Ihren eigenen Klassen mit Ihren eigenen Ereignissen sollten Sie Ihre eigene Realisierung von Add/Remove-Methoden für Ereignisse definieren, um Ihr Problem zu lösen.

4

Ich habe das schon mal gemacht .... es geht davon aus, dass es akzeptabel ist, dass der letzte Teilnehmer angerufen wird.

+4

nett, für diejenigen Geschwindigkeitsleser, die es vielleicht verpasst haben, ist dies die wichtige Linie. ChangedEventHandler = Wert; anstelle von + =. Gut für den einmaligen Gebrauch - funktioniert vielleicht in einigen Fällen für mich - danke! – ScottCate

Verwandte Themen