2011-12-14 7 views
32

Recientemente volví a C# de estar en el terreno de Objective-C, y las palabras clave async/await en C# 5 parecen divertidas. Pero todavía estoy tratando de manejar la sintaxis adecuada.¿Cuál es la firma del método para pasar un delegado asíncrono?

Quiero declarar un método que toma un delegado asíncrono como parámetro, pero estoy teniendo problemas para obtener la sintaxis de la persona que llama y la llamada correcta. ¿Puede alguien proporcionar una muestra de código que muestre la declaración del método, la llamada y una llamada al delegado?

Estoy pensando que la declaración sería algo como lo siguiente. Tenga en cuenta que esta función no es asincrónica; es decir, su asincronía es independiente del delegado.

void DoSomethingWithCallback(async delegate foo(int)) 
{ 
    ... 
    foo(42); 
    ... 
} 

La llamada sería algo así como:

DoSomethingWithCallback(async (int x) => { this.SomeProperty = await SomeAsync(x); }); 

Por supuesto, nada de esto compila y la mayoría de las muestras que he visto asuma que tiene un campo de una o propiedad que es el delegado, en lugar de el delegado anónimo que me gustaría usar

+0

tan cerca como puedo decir, no hay forma de especificar un delegado en línea, como lo hago en la pregunta anterior. Para usar un delegado como parámetro de método, un tipo de delegado debe declararse fuera del alcance de la clase. – AndrewS

Respuesta

47

Una función que toma un delegado como parámetro debe usar un tipo de delegado con nombre; a diferencia de Objective-C, no puede declarar un tipo de delegado anónimo en línea en la definición de la función. Sin embargo, se proporcionan los productos genéricos Acción <> y Func <> para que no tenga que declarar un tipo nuevo usted mismo. En el siguiente código, supongo que el delegado toma un solo int como parámetro.

void DoSomethingWithCallback(Func<int,Task> callbackDelegate) 
{ 
    Task t = callbackDelegate(42); 
} 

Si esta función no realmente hacer cualquier cosa con el objeto de tareas devuelto (como con el código que se muestra más arriba), en su lugar puede utilizar Action<int> como el tipo de delegado. Si usa Acción, todavía puede declarar el delegado asincrónico (a continuación) pero se ignora el objeto Tarea implícita devuelto.

La sintaxis lambda para llamar a la función anterior es sencilla y la sintaxis que utilizó en la pregunta es correcta. Tenga en cuenta que el tipo de parámetro no necesita ser especificada aquí, ya que puede resultar:

DoSomethingWithCallback(async (intParam) => { this.myint = await Int2IntAsync(intParam); }); 

También se puede pasar un método o delegar variable, si se desea, en lugar de utilizar la sintaxis lambda:

async Task MyInt2Int(int p) { ... } 
Func<int,Task> myDelegate; 
void OtherMethod() 
{ 
    myDelegate = MyInt2Int; 
    DoSomethingWithCallback(myDelegate); // this ... 
    DoSomethingWithCallback(MyInt2Int); // ... or this. 
} 
5

El tipo de devolución del método de signaturas es Task si no hay un tipo de devolución, o Task<T> si hay un tipo de devolución.

Tho, no estoy 100% seguro si puedes tener async lambdas así.

En el método que consume la tarea, o bien 'aguarda' la tarea o usa las propiedades y métodos en Tarea para obtener el resultado.

+10

Sí, estamos soportando async lambdas. Bastante astuto si lo digo yo mismo. –

+0

@Eric: bastante resbaladizo, de hecho. –

Cuestiones relacionadas