Gibt es eine Möglichkeit festzustellen, ob einem Objekt ein Ereignishandler hinzugefügt wurde? Ich serialisiere eine Liste von Objekten in den Sitzungsstatus / aus dem Sitzungsstatus heraus, damit wir den SQL-basierten Sitzungsstatus verwenden können ... Wenn für ein Objekt in der Liste eine Eigenschaft geändert wurde, muss es markiert werden, was der Ereignishandler zuvor ordnungsgemäß erledigt hat . Wenn die Objekte jetzt deserialisiert werden, wird der Ereignishandler nicht mehr abgerufen.
In einem Anfall von leichtem Ärger habe ich gerade den Ereignishandler zur Get-Eigenschaft hinzugefügt, die auf das Objekt zugreift. Es wird jetzt aufgerufen, was großartig ist, außer dass es ungefähr fünfmal aufgerufen wird. Ich denke, der Handler wird jedes Mal hinzugefügt, wenn auf das Objekt zugegriffen wird.
Es ist wirklich sicher genug, um es einfach zu ignorieren, aber ich würde es lieber so viel sauberer machen, indem ich überprüfe, ob der Handler bereits hinzugefügt wurde, also mache ich das nur einmal.
Ist das möglich?
BEARBEITEN: Ich habe nicht unbedingt die volle Kontrolle darüber, welche Ereignishandler hinzugefügt werden. Es reicht also nicht aus, nur auf Null zu prüfen.
Antworten:
Wie von @Telos erwähnt, können Sie EventHandler von außerhalb der definierenden Klasse nur auf der linken Seite von a
+=
oder a verwenden-=
. Wenn Sie also die definierende Klasse ändern können, können Sie eine Methode zum Durchführen der Prüfung bereitstellen, indem Sie prüfen, ob der Ereignishandler vorhanden ist.null
Wenn ja, wurde kein Ereignishandler hinzugefügt. Wenn nicht, können Sie möglicherweise die Werte in Delegate.GetInvocationList durchlaufen . Wenn einer dem Delegaten entspricht, den Sie als Ereignishandler hinzufügen möchten, wissen Sie, dass er vorhanden ist.Und dies könnte leicht geändert werden, um "den Handler hinzuzufügen, wenn er nicht da ist". Wenn Sie keinen Zugriff auf die Innereien der Klasse haben, die das Ereignis enthüllt, müssen Sie möglicherweise
-=
und+=
, wie von @Lou Franco vorgeschlagen, erkunden.Es ist jedoch möglicherweise besser, die Art und Weise, in der Sie diese Objekte in Betrieb nehmen und außer Betrieb nehmen, erneut zu überprüfen, um festzustellen, ob Sie keine Möglichkeit finden, diese Informationen selbst zu verfolgen.
quelle
Delegate.Equals(objA, objB)
Sie diese Option, wenn Sie überprüfen möchten, ob genau dieselbe Delegate vorhanden ist. Ansonsten vergleiche die Eigenschaften einzeln gerneif(objA.Method.Name == objB.Method.Name && objA.Target.GetType().FullName == objB.Target.GetType().FullName)
.Ich bin kürzlich zu einer ähnlichen Situation gekommen, in der ich nur einmal einen Handler für eine Veranstaltung registrieren musste. Ich habe festgestellt, dass Sie die Registrierung zuerst sicher aufheben und dann erneut registrieren können, auch wenn der Handler überhaupt nicht registriert ist:
Beachten Sie, dass Sie bei jeder Registrierung Ihres Handlers sicherstellen, dass Ihr Handler nur einmal registriert wird. Klingt für mich nach einer ziemlich guten Übung :)
quelle
Wenn dies der einzige Handler ist, können Sie überprüfen, ob das Ereignis null ist. Wenn dies nicht der Fall ist, wurde der Handler hinzugefügt.
Ich denke, Sie können sicher - = bei dem Ereignis mit Ihrem Handler aufrufen, auch wenn es nicht hinzugefügt wurde (wenn nicht, können Sie es abfangen) -, um sicherzustellen, dass es nicht vorhanden ist, bevor Sie es hinzufügen.
quelle
Dieses Beispiel zeigt, wie mit der Methode GetInvocationList () Delegaten an alle hinzugefügten Handler abgerufen werden. Wenn Sie sehen möchten, ob ein bestimmter Handler (eine bestimmte Funktion) hinzugefügt wurde, können Sie ein Array verwenden.
Sie können verschiedene Eigenschaften in der Method-Eigenschaft des Delegaten untersuchen, um festzustellen, ob eine bestimmte Funktion hinzugefügt wurde.
Wenn Sie sehen möchten, ob nur eine angehängt ist, können Sie einfach auf null testen.
quelle
Wenn ich Ihr Problem richtig verstehe, haben Sie möglicherweise größere Probleme. Sie sagten, dass andere Objekte diese Ereignisse möglicherweise abonnieren. Wenn das Objekt serialisiert und deserialisiert wird, verlieren die anderen Objekte (die Sie nicht kontrollieren können) ihre Ereignishandler.
Wenn Sie sich darüber keine Sorgen machen, sollte es gut genug sein, einen Verweis auf Ihren Event-Handler zu führen. Wenn Sie sich Sorgen machen, dass andere Objekte ihre Ereignishandler verlieren, sollten Sie Ihre Caching-Strategie überdenken.
quelle
Die einzige Möglichkeit, die für mich funktioniert hat, besteht darin, eine boolesche Variable zu erstellen, die ich beim Hinzufügen des Ereignisses auf true gesetzt habe. Dann frage ich: Wenn die Variable falsch ist, füge ich das Ereignis hinzu.
Diese Variable kann global sein.
quelle
Ich stimme der Antwort von alf zu, aber wenig Modifikation ist ,, zu verwenden,
quelle
quelle