c# - publicador - patron publicar suscribir
¿Los suscriptores del evento se llaman por orden de suscripción? (5)
¿Es seguro asumir que los suscriptores del evento se llaman por orden de suscripción?
Ejemplo:
void One(object sender, EventArgs e) {}
void Two(object sender, EventArgs e) {}
event EventHandler foo;
foo += One;
foo += Two;
¿Uno () siempre se llama antes de Dos () cuando se dispara el evento?
Editar:
Por supuesto que no debes confiar en eso, solo estaba pensando. La idea era que los delegados de multidifusión son similares al patrón COMMAND. Entonces me preguntaba. Usualmente usarías una colección que mantiene el orden de los COMANDOS para que puedas deshacer / rehacer / lo que sea.
Dado que la implementación, sí, siempre se llamarán en ese orden.
Si el evento realmente utiliza alguna forma extraña y maravillosa de manejar suscripciones, podría hacer cosas diferentes, pero las implementaciones "normales" harán lo correcto.
Para ser claros, suscribirse a un manejador de eventos solo significa invocar la parte "agregar" apropiada de un evento. Si el evento maneja esto, haz algo como:
myHandler += value;
eso se traduce a
myHandler = Delegate.Combine(myHandler, value);
y Delegate.Combine garantiza el orden. Sin embargo, si tuviste un evento como este:
private LinkedList<EventHandler> eventHandlers = new LinkedList<EventHandler>;
public event EventHandler Foo
{
add
{
eventHandlers.AddFirst(value);
}
remove
{
// do stuff here too
}
}
y luego disparó el evento haciendo algo como:
foreach (EventHandler handler in eventHandlers)
{
handler(this, EventArgs.Empty);
}
entonces los manipuladores serían llamados en el orden inverso.
Resumen : para todos los eventos sanos, puede confiar en el pedido. En teoría, los eventos pueden hacer lo que quieran, pero nunca he visto un evento que no mantenga el orden apropiado.
Incluso si son llamados en el orden correcto, intentaré no escribir código que dependa de que un delegado anterior haya sido despedido para que funcione correctamente.
Si Two () depende de algo que One () está haciendo, entonces adjunte un único delegado que llame a los dos métodos en el orden correcto, o haga que Two () invoque One () cuando sea necesario.
La respuesta rápida sería "No es asunto tuyo" :)
Un evento es asincrónico por naturaleza. Esto significa que no está esperando que un evento sea despedido o que espere que ocurra en un momento dado. Simplemente suceden y luego tomas medidas. Querer saber "cuándo" o tratar de descubrir "cómo" va a romper esta naturaleza.
¿Tal vez en este caso no necesita un enfoque basado en eventos para hacer las cosas?
Lo que Jon Skeet dijo es técnicamente correcto para la implementación actual, pero tal vez no lo haga en c # 8.5 o VBasic 15.0. Confiar en los detalles de la implementación siempre hará más daño que bien.
Presta mucha atención a las advertencias dadas por Jon Skeet: "Dada la implementación ...". En otras palabras, realice el cambio más leve (múltiples hilos, otros manejadores, etc.) y corre el riesgo de perder la invarianza de orden de ejecución.
NO confíe en el orden de eventos . Todos los despachos de eventos deben ser lógicamente independientes, como si estuvieran ocurriendo en paralelo. Los eventos son acciones lógicamente independientes.
Daré un paso más y afirmaré que, si tiene que asumir un pedido de activación de eventos, tiene un defecto grave de diseño y / o está haciendo un mal uso de los eventos.
En general, se espera que los suscriptores de eventos se comporten independientemente el uno del otro. No debería haber ninguna diferencia si se invocaron por orden de suscripción, orden inverso de suscripción o en orden aparentemente aleatorio que varía arbitrariamente cada vez que se genera el evento. Los suscriptores no deberían preocuparse por otros suscriptores que ejecutan antes o después de ellos.
Sin embargo, en algunos casos, los eventos se pueden usar en contextos donde tal ordenamiento es importante. A los manejadores de eventos se les puede pasar un objeto mutable, y se espera que hagan uso de las mutaciones de dicho objeto en el manejador anterior. En tal caso, si la operación significativa de los eventos requeriría que se realizaran en un orden particular, y siempre que se hayan cumplido los requisitos documentados para los suscriptores, se debe esperar que los eventos se ejecuten en el orden dado.