2008-11-13 22 views
9

Estoy escribiendo la Aplicación A y la DLL B, ambas en C# .NET. ¿Cómo hago la siguiente:C# callback from DLL

  1. Una función llama en B
  2. Quieres B para usar delegado/devolución de llamada para actualizar el estado de la interfaz de usuario de A

Ésta es no sobre BackgroundWorker .. Esa parte funciona bien en A. Lo que no puedo ver es cómo informarle a B qué función llamar en A.

Respuesta

6

Tiene dos opciones. El más común es tener un evento en B y tener su UI en A suscribirse a ese evento. B luego dispara ese evento.

La segunda opción es pasar un delegado de A como un parámetro a la llamada de método en B. B puede invocar a ese delegado.

+0

Iba por la segunda opción, pero la sintaxis me tiene desconcertado. –

+0

Te estás perdiendo una tercera opción. Puede crear un delegado en A para sombrear el método B, de modo que B nunca necesite saber nada al respecto. Excelente para llamar métodos en bibliotecas de terceros de manera asincrónica que normalmente no lo soportaría. –

+0

Terminé probando la primera y la segunda opción. La sintaxis para el segundo fue más limpia en mi caso. ¡Gracias! –

1

Pase el objeto de devolución de llamada en la llamada A make to B. Utilice una interfaz (o bibliotecas estrechamente enlazadas). Asegúrese de que el objeto de devolución de llamada tenga en cuenta el hilo y sea seguro para el hilo.

12

Para ampliar la respuesta de Rob Prouse, debe declarar un delegado y luego pasarle un método de coincidencia.

En B:

public delegate void CallbackDelegate(string status); 

public void DoWork(string param, CallbackDelegate callback) 
{ 
    callback("status"); 
} 

En A:

public void MyCallback(string status) 
{ 
    // Update your UI. 
} 

Y cuando se llama al método:

B.DoWork("my params", MyCallback); 
+1

¡Gracias! Acababa de resolver esto, así que es bueno tener tu confirmación. –

+0

Por supuesto, si A y B están en ensamblajes diferentes, es posible que tenga que pegar el delegado en su propio ensamblado para evitar problemas de dependencia recursivos. – Soraz

+0

Si el delegado se declara en B, ¿cómo obtendría una dependencia circular? –

1

Si controlas B, entonces Rob Prouse o Brody de las respuestas se trabaja bien.

Pero, ¿y si no puedes cambiar B? En ese caso, siempre puede ajustar un método en un delegado de su propia creación, siempre que la firma coincida con la firma del método de destino.

Entonces, supongamos que tiene una instancia de clase llamada B con un método público llamado b() (desde el ensamblado B dll, por supuesto). La clase A en la aplicación A puede llamarlo asíncronamente así:

public class A 
{ 
    delegate void BDelegate(); 

    public void BegineBMethod() 
    { 
     BDelegate b_method = new BDelegate(B.b); 
     b_method.BeginInvoke(BCallback, null); 
    } 

    void BCallback(IAsyncResult ar) 
    { 
     // cleanup/get return value/check exceptions here 
    } 
}