2011-05-18 16 views
11

He desarrollado una aplicación C# que hace uso intensivo de eventos. Ahora, esta aplicación ocasionalmente hace cosas divertidas que no puedo entender o rastrea una causa específica por la que deberían ocurrir. Creo que la causa de estos funcionamientos intermitentes es algún tipo de concurrencia o condición de carrera que no anticipé.¿Cuándo exactamente se ejecutan los eventos en C#?

¿Cómo se manejan los eventos en C#? Si se produce un evento, ¿se ejecutará (a) la parte del código adjunta a ese evento inmediatamente? ¿O el evento (b) se colocará en una pila de eventos y se ejecutará siempre que .NET lo considere adecuado para la ejecución mientras se ejecuta otro código mientras tanto?

Respuesta

12

Si se produce un evento, será la porción del código adjunto a ese evento se ejecutará de inmediato?

Bueno, sí y no. Los eventos son delegados de multidifusión, por lo que puede haber cero, una o muchas "partes de código" asociadas a un evento. En el escenario donde hay muchos, claramente uno de ellos tiene que ir primero y uno de ellos tiene que ir en segundo lugar. El que va en segundo lugar no se ejecuta inmediatamente después del evento que se plantea; se ejecuta inmediatamente después de que el primer controlador de eventos complete normalmente.

¿El evento se pondrá en una pila de eventos y se ejecutará cada vez que .NET lo considere adecuado para la ejecución mientras se ejecuta otro código mientras tanto?

Supongamos que su aplicación está mal escrita y cuelga la IU. Mientras la IU está colgada, el usuario hace clic en el botón 1 y el botón 2. Como la aplicación está bloqueada, no ocurre nada visible. Los eventos para los botones 1 y 2 en los que se hace clic no se disparan. Pero Windows ha creado una cola de mensajes y ha puesto en cola el hecho de que el botón 1 y el botón 2 tienen clics pendientes que deben procesarse cuando la aplicación se separa. Cuando se bombea el bucle de mensaje, el evento de clic del botón 1 se dispara. Cuando se hace lo suyo, el ciclo de mensajes se bombea de nuevo y el evento de clic del botón 2 se dispara.

Así que sí, en ese sentido los eventos se ponen en cola y se ejecutan más tarde, pero no es "cuando .NET lo considera adecuado"; es cuando el hilo que está procesando la cola de mensajes comienza a procesar la cola de mensajes nuevamente. No hay una misteriosa política de Windows aquí que controle tu código.

+0

"Cuando se hace lo suyo, el ciclo de mensajes se bombea nuevamente y el botón 1 clic dispara el evento". ¿Te refieres al botón 2 clic en evento? " – Brian

5

C# events, al igual que el resto de delegados, se ejecutan inmediatamente cuando se activan.

8

Todo depende del código de generación de eventos (y suscripción).

Si está elevando el evento como este:

EventHandler handler = MyEvent; 

if (handler != null) 
{ 
    handler(this, EventArgs.Empty); 
} 

o algo similar, entonces todos los controladores de eventos se ejecutará inmediatamente. Esa es la implementación típica de ... tienes que trabajar un poco más para poner cada delegado de evento en la cola de mensajes de WinForms o algo así.

Si pudiera brindarnos más información sobre los eventos de los que habla y cómo se implementan, podremos ayudarlo más.

Para obtener más información sobre eventos y delegados (y la diferencia entre ellos) es posible que desee leer my article on the topic.

2

A menos que se implemente explícitamente de lo contrario, los eventos se llaman sincrónicamente.

Normalmente el código que activa un evento que se parece a:

public event EventHandler MyEvent; 

protected virtual void OnMyEvent() 
{ 
    EventHandler handler = MyEvent; // keep a copy to avoid race conditions 
    if (handler != null) 
     handler(this, EventArgs.Empty); 
} 

Como se puede ver en el código, controladores de eventos son llamados inmediatamente y de forma sincronizada a partir del método OnMyEvent.

1

Creo que su pregunta ha sido contestada aquí:

Are Event Handlers processed Asynchronously?

En resumen, que depende de su aplicación, pero el manejo de eventos predeterminado es procesada de forma sincrónica. Sin embargo, hay formas de hacerlo asíncrono.

0

Como se indica en el gráfico anterior, depende completamente del código que está provocando el evento o manejando el evento.

Lo que falta en los ejemplos anteriores es el código adecuado sobre cómo generar/gestionar eventos. Soy consciente de que son solo ejemplos rápidos, pero, sin embargo, las buenas prácticas son importantes.

Si quieres buenos ejemplos/material sobre cómo los eventos pueden ser adecuadamente procesados ​​en C#, se podrían echar un vistazo a este artículo: http://www.codeproject.com/KB/cs/event_fundamentals.aspx

Cuestiones relacionadas