Wie entfernen Sie sich von einem Event-Handler?

8

Was ich tun möchte, ist im Grunde eine Funktion aus einem Ereignis zu entfernen, ohne den Namen der Funktion zu kennen.

Ich habe ein FileSystemWatcher . Wenn eine Datei erstellt / umbenannt wird, überprüft sie ihren Namen. Wenn es übereinstimmt, wird es an einen bestimmten Ort verschoben. Wenn die Datei jedoch gesperrt ist, erzeugt sie ein Lambda, das an das Tick-Ereignis eines Timers angehängt wird und wartet, bis die Datei nicht gesperrt ist. Wenn dies nicht der Fall ist, wird die Datei verschoben und anschließend aus dem Ereignishandler entfernt. Ich habe viele Möglichkeiten gesehen, wie ich die Instanz beibehalten oder eine benannte Methode erstellen kann. Ich kann keinen von denen hier tun. Was sind meine Optionen?

    
It'sNotALie. 24.05.2013, 12:16
quelle

2 Antworten

20

Es gibt keine einfache Methode, um dies zu erreichen.

Bevorzugter Ansatz:

Ich verstehe nicht, warum Sie den Delegierten nicht speichern können. Sie müssen die Instanz nicht als ein Feld speichern. Es kann eine lokale Variable sein, die von Ihrem anonymen Ereignishandler erfasst wird:

%Vor%

Ich kann mir kein einziges Szenario vorstellen, wo Sie das nicht verwenden können.

Alternative Vorgehensweise ohne den Delegaten zu speichern:

Wenn Sie jedoch ein solches Szenario haben, wird es ziemlich kompliziert Sie müssen den Delegaten finden, der dem Ereignis als Handler hinzugefügt wurde. Weil Sie es nicht gespeichert haben, ist es ziemlich schwer, es zu erhalten. Es gibt kein this , um einen Delegierten der aktuell ausgeführten Methode zu erhalten.

Sie können GetInvocationList() nicht für das Ereignis verwenden. Da der Zugriff auf ein Ereignis außerhalb der Klasse, in der es definiert ist, auf das Hinzufügen und Entfernen von Handlern beschränkt ist, z. B. += und -= .

Das Erstellen eines neuen Delegaten ist ebenfalls nicht möglich. Sie können zwar Zugriff auf das Objekt MethodInfo erhalten, das Ihre anonyme Methode definiert, aber Sie können nicht auf die Instanz der Klasse zugreifen, in der diese Methode deklariert ist. Diese Klasse wird vom Compiler automatisch generiert und ruft this innerhalb des anonymen Objekts auf Die Methode gibt die Instanz der Klasse zurück, in der Ihre normale Methode definiert ist.

Der einzige Weg, den ich gefunden habe, ist, das Feld - falls vorhanden - zu finden, das das Event verwendet, und% code% darauf zu nennen. Der folgende Code demonstriert dies mit einer Dummy-Klasse:

%Vor%

Beachten Sie, dass die Zeichenfolge GetInvocationList() , die an "Bar" übergeben wird, der genaue Name des vom Ereignis verwendeten -Feldes sein muss. Dies führt zu zwei Problemen:

  1. Das Feld kann anders benannt werden, z. bei Verwendung einer expliziten Ereignisimplementierung. Sie müssen den Feldnamen manuell herausfinden.
  2. Es könnte überhaupt kein Feld geben. Dies passiert, wenn das Ereignis eine explizite Ereignisimplementierung verwendet und nur an ein anderes Ereignis delegiert oder die Delegierten auf andere Weise speichert.

Fazit:

Der alternative Ansatz beruht auf Implementierungsdetails. Verwenden Sie ihn daher nicht, wenn Sie ihn vermeiden können.

    
Daniel Hilgarth 24.05.2013, 12:59
quelle
0

Schritte zum Entfernen des Ereignishandlers mit Lambda-Ausdruck:

%Vor%     
Gomes 19.11.2014 10:19
quelle

Tags und Links