Sagen wir, dass ich diese (unvollständige) Klasse habe, in der ich ein Ereignis erstelle, ohne es einer Variablen zuzuweisen, um es threadsicher zu machen:
%Vor%Wäre es sicher, einen Event-Handler von sich selbst abzubestellen, oder könnte es ein Problem geben, ähnlich wie beim Entfernen von Objekten aus einer Sammlung während der Aufzählung?
%Vor%Um die andere Antwort etwas zu verdeutlichen:
Ereignisse basieren auf Delegierten (in fast allen Fällen). Delegierte sind unveränderlich. Dies gilt auch für Multicast-Delegaten.
Beim Aufrufen eines Ereignisses wird der Delegat geladen und dann aufgerufen. Wenn das Feld, in dem der Delegat gespeichert ist, geändert wird, wirkt sich dies nicht auf den bereits geladenen Delegaten aus.
Es ist daher sicher, das Ereignis vom Handler zu modifizieren. Diese Änderungen haben keinen Einfluss auf den gerade ausgeführten Aufruf. Das ist garantiert.
All dies gilt nur für Ereignisse, die von einem Delegaten unterstützt werden. C # und die CLR unterstützen benutzerdefinierte Ereignisse, die überhaupt etwas tun können.
Es wäre jedoch sicher, nur dass es keine Garantie dafür gibt, dass der Code in SomeEventHandler
nur einmal ausgeführt wird. Eine Race-Bedingung kann auftreten, wenn Sie Multithread-Code haben.
Bearbeiten : Wenn Sie eine Veranstaltung abbestellen, können Sie im Hintergrund die Delegierten kombinieren, um eine Liste der Teilnehmer zu erstellen. (Viele Details finden Sie auf Artikel von Jon Skeet, dem Mann selbst )
Beachten Sie, dass das Ereignis Sperren verwendet, um die Threadsicherheit für die Delegate-Kombination zu garantieren. Sobald Sie einen Delegierten mit Ihrer Veranstaltung verbunden haben, erhalten Sie eine Liste mit Delegierten. Wenn jedoch ein Ereignis ausgelöst wird, ist garantiert, dass die neueste Version der kombinierten Delegierten verwendet wird. (Siehe Thread-sichere Ereignisse ), aber das hat nichts damit zu tun, dass das Ereignis im Inneren des Ereignisses aufgehoben wurde.
Ich hoffe, meine Bearbeitung bietet genug Klärung:)