2011-05-12 39 views
5

Una pregunta simple sobre devoluciones de llamada. ¿Las funciones de devolución de llamada vuelven a la siguiente línea en la función de llamada después de la finalización?devolución de llamada en C#, orden de llamada y devolución

class A 
{ 
public delegate void A(); 
public event A onA; 

public void func() 
{ 
    //some code 1 
    onA(); 
    //some code 2 
} 

Así que la pregunta es irá evento Oña y ejecutar la respectiva guía y luego volver a 'un cierto código 2' bits o es asíncrono y este código no esperarán a que el evento sea totalmente manejado?

Espero que la pregunta sea clara.

Gracias }

Respuesta

2

Sí, en su ejemplo onA() activará todos los manejadores de eventos conectados a A para disparar. Son solo métodos que serán llamados. Después de que todos sean llamados, el control volverá a func().

No es asíncrono, solo está utilizando un hilo. Todo sucederá en un orden bien definido.

Una buena forma de experimentar sería recorrer el código en su ejemplo utilizando el depurador incorporado.

+0

Muchas gracias. Eso es lo que esperaba. Lo probará usando el depurador como sugirió. – user642770

3

La forma en que solía delegado: es sincrónico. Si desea asincronizar, debe invocar a delegado con el método: BeginInvoke.

1

No, llamar a un evento no es una operación de sincronización. Su código func() solo continuará después de que onA() termine de ejecutarse.

Utilizaría BeginInvoke o Threading si quiere ejecutar código assync.

Más información acerca de delegate invoca here.

0

Como han señalado otros, esto es completamente sincrónico. Si quisiera ejecutar esto de forma asíncrona, tendría que escribir esto de manera diferente.

Además, si el evento 'onA' no está suscrito, onA() generará una excepción de referencia nula.

El patrón habitual es definir un evento 'Foo' y un método 'OnFoo' al que llama cuando se produce el evento. Desde el nombre del evento Sospecho que esto es lo que deseo - por ejemplo: -

class Foo // Class and member names must be distinct 
{ 
    public delegate void ADelegate(); 
    public event ADelegate A; 

    private void OnA() 
    { 
     if(A != null) 
      A(); 
    } 

    public void Func() 
    { 
     // Some code... 
     OnA(); 
     // More code... 
    } 
} 

Si desea llamar a los controladores de eventos suscritos de forma asíncrona puede utilizar BeginInvoke() y EndInvoke() así: -

class Foo // Class and member names must be distinct 
{ 
    public delegate void ADelegate(); 
    public event ADelegate A; 

    private void OnA() 
    { 
     if (A == null) return; 

     // There may be multiple subscribers, invoke each separately. 
     foreach(ADelegate del in A.GetInvocationList()) 
      del.BeginInvoke(SubscriberCallback, del); 
    } 

    private void SubscriberCallback(IAsyncResult result) 
    { 
     var del = (ADelegate) result.AsyncState; 
     del.EndInvoke(result); 
     // Do something in the callback... 
    } 

    public void Func() 
    { 
     // Some code... 
     OnA(); 
     // More code... 
    } 
} 

Tenga en cuenta que este código no espera esperar para terminar la ejecución de los suscriptores del evento, tendrías que pasar el resultado asincrónico a través de la llamada al evento para garantizar que esto ocurra.

Tenga en cuenta que la 'devolución de llamada' es el método que especifica en BeginInvoke asincrónico (ya que se 'vuelve a llamar' una vez que se realiza el trabajo asincrónico) y no regresa a Func() ya que se ejecuta en hilo separado

+0

También hay otros problemas, como siempre con el subprocesamiento, es probable que desee hacer algún bloqueo aquí para evitar la devolución de llamada y EndInvoke() antes de que Func() lo haga (esto da como resultado una excepción). – ljs

Cuestiones relacionadas