Los controladores de eventos no están seguros?

Así que he leído todo eso en lugar de llamar un evento directamente con

if (SomeEvent != null) SomeEvent(this, null); 

debería estar haciendo

 SomeEventHandler temp = SomeEvent; if (temp != null) temp(this, null); 

¿Por qué esto es tan? ¿Cómo se convierte la segunda versión en un hilo seguro? cual es la mejor practica?

Los eventos son realmente azúcar sintáctico sobre una lista de delegates. Cuando invocas el evento, esto realmente itera sobre esa lista e invoca a cada delegado con los parámetros que has pasado.

El problema con los hilos es que podrían estar agregando o eliminando elementos de esta colección al suscribirse / darse de baja. Si lo hacen mientras itera la colección, esto causará problemas (creo que se lanza una excepción)

La intención es copiar la lista antes de iterarla, para que esté protegido contra los cambios en la lista.

Nota: Sin embargo, ahora es posible invocar a su oyente incluso después de anular la suscripción, por lo que debe asegurarse de manejarlo en su código de escucha.

OMI, las otras respuestas omiten un detalle clave: que los delegates (y por lo tanto los eventos) son inmutables . La importancia de esto es que la suscripción o anulación de la suscripción a un controlador de eventos no se limita a anexar / eliminar a una lista, sino que reemplaza la lista por una nueva con un elemento adicional (o uno menos) en ella.

Como las referencias son atómicas, esto significa que en el momento en que lo hace:

 var handler = SomeEvent; 

ahora tiene una instancia rígida que no puede cambiar, incluso si en el siguiente picosegundo se anula la suscripción a otro subproceso (haciendo que el campo de evento real se vuelva null ).

Entonces prueba null e invoca, y todo está bien. ¡Nótese, por supuesto, que todavía existe el escenario confuso del evento que se plantea sobre un objeto que piensa que se dio de baja hace un picosegundo!

La mejor práctica es la segunda forma. La razón es que otro subproceso podría SomeEvent o alterar SomeEvent entre la prueba ‘ if ‘ y la invocación.

Aquí hay una buena reseña sobre los eventos de .NET y las condiciones de la carrera con hilos. Cubre algunos escenarios comunes y tiene algunas buenas referencias en él.

Espero que esto ayude.