En cuanto a la invocación del delegado, la respuesta es sí.
Invocar a un delegado es seguro para subprocesos porque los delegados son inmutables. Sin embargo, debe asegurarse de que exista un delegado primero. Esta comprobación puede requerir algunos mecanismos de sincronización según el nivel de seguridad deseado.
Por ejemplo, lo siguiente podría arrojar un NullReferenceException
si SomeDelegate
se establecieron en nulo por otro hilo entre la verificación nula y la invocación.
if (SomeDelegate != null)
{
SomeDelegate();
}
El siguiente es un poco más seguro. Aquí estamos explotando el hecho de que los delegados son inmutables. Incluso si otro hilo modifica SomeDelegate
, el código se endurece para evitar ese molesto NullReferenceException
.
Action local = SomeDelegate;
if (local != null)
{
local();
}
Sin embargo, esto podría resultar en el delegado no se ejecuta si SomeDelegate
se le asignó un valor no nulo en otro hilo. Esto tiene que ver con un problema sutil de barrera de memoria. El siguiente es el método más seguro.
Action local = Interlocked.CompareExchange(ref SomeDelegate, null, null);
if (local != null)
{
local();
}
En cuanto a la ejecución del procedimiento referenciado por el delegado de la respuesta es no.
Deberá proporcionar sus propias garantías de seguridad de hilos a través del uso de mecanismos de sincronización.Esto se debe a que CLR no proporciona automáticamente garantías de seguridad de subprocesos para la ejecución de delegados. Puede ser que el método no requiera ninguna sincronización adicional para que sea seguro, especialmente si nunca tiene acceso al estado compartido. Sin embargo, si el método lee o escribe desde una variable compartida, entonces deberá considerar cómo protegerse contra el acceso simultáneo desde múltiples hilos.
¿Qué podría cambiar en un delegado? (Su comentario es correcto sobre los eventos, pero no veo qué puede cambiar sobre un delegado). –
@ agent-j: eso es inmaterial; la implementación subyacente puede cambiar, pero la documentación actual es la que se indica. –