Keine der beiden Versionen ist threadsafe, je nachdem, was Sie unter "threadsafe" verstehen. Betrachten Sie Ihre zweite Version:
var h = handler;
if (h!= null)
h(sender, args);
"Handler" ist eine Kopie eines Feldes, das einen unveränderlichen Delegaten enthält. Angenommen, das Feld wird nach der Nullprüfung in einem anderen Thread zu "null" mutiert. Ihr Code stürzt in diesem Fall nicht ab, weil Sie eine Kopie des ursprünglichen Nicht-Null-Werts erstellt haben. Aber nur nicht Absturz macht nicht das Programm Thread sicher. Ein Programm, das nicht abstürzt, aber immer noch die falschen Ergebnisse liefert, ist immer noch nicht threadsicher.
Angenommen, der andere Thread hat das Ereignisfeld auf null gesetzt, hat auch einen Zustand mutiert, in dem der vorherige Inhalt korrekt ausgeführt werden musste. Sie werden jetzt einen Event-Handler ausführen, der vom Zustand abhängt, der gerade in einem anderen Thread mutiert wurde; Sie führen einen veralteten Event-Handler.
Es gibt keine einfache Möglichkeit, sich vor diesem Problem zu schützen; Wenn das die Situation ist, in der Sie sich befinden, müssen Sie Ihre Threading-Logik sehr sorgfältig entwerfen, um mit der Situation fertig zu werden.
Design und Implementierung Details von Ereignissen in Bezug auf Threading http://StackOverflow.com/Questions/786383/c-Events-and-Thread-Safety – user44298