2012-09-03 13 views
14

Si tengo un método normal que yo quiero hacer asíncrono:¿Por qué utilizar async y esperar con Task <>?

public int Foo(){} 

que haría:

public Task<int> FooAsync(){ 
    return Task.Run(() => Foo()); 
} 

qué iba a hacer:

public async Task<int> FooAsync(){ 
    return await Task.Run(() => Foo()); 
} 

La forma en que planeo use esto es:

FooAsync().ContinueWith((res) => {}); 

Quiero que el método se ejecute sin parar, pero quiero que se active algo así como una devolución de llamada, de ahí el ContinueWith. Pero con la segunda versión, ¿hay algún punto para usarla?

Respuesta

14

En mi entendimiento, sólo es necesario async y await cuando se escribe un método que hace algunos asíncrono llama interior, pero que le gustaría que a mirada como si no lo hace. En otras palabras, desea escribir y leer el código como si fuera un código secuencial normal, manejar las excepciones como si fuera un código secuencial normal, devolver los valores como si fuera un código secuencial normal, y así sucesivamente. Entonces la responsabilidad del compilador es reescribir ese código con todas las devoluciones de llamada necesarias preservando la lógica.

Su método es tan simple que no creo que necesite esa reescritura en absoluto, solo puede devolver la tarea, pero quien la consuma puede querer await por su valor de retorno.

+0

¡excelente descripción! – paulsm4

+0

Gracias, @ paulsm4. Debo decir que estoy volviendo a contar lo que escuché recientemente, creo, es de http://hanselminutes.com/327/everything-net-programmers-know-about-asynchronous-programming-is-wrong, pero no 100% seguro. Todavía no tengo mucha experiencia con la función de sincronización, por lo que podría estar equivocado y me gustaría saber más, tal vez asincrónico proporciona algunos beneficios en este caso. –

+2

Además, es posible que desee leer [¿Debo exponer los contenedores asíncronos para los métodos síncronos?] (Http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) (La respuesta casi siempre es "no"; si tiene un método sincrónico, entonces dele una firma de método sincrónico). –

5

qué iba a hacer:

public async Task<int> FooAsync() 
{ 
    return await Task.Run(() => Foo()); 
} 

Usted no lo haría. Su versión anterior devuelve Tarea que ya está a la espera. Esta nueva versión no agrega nada.

La forma en que la intención de utilizar esto es:

FooAsync().ContinueWith((res) => {}); 

Quiero el método de sólo correr sin parar, pero quiero algo así como una devolución de llamada a ser despedido, por lo tanto el ContinueWith.

Esto es donde la diferencia viene en Vamos a dar cuerpo a su ejemplo, un poquito:.

void DoAsyncStuff() 
{ 
    FooAsync().ContinueWith((res) => { DoSomethingWithInt(res.Result) }); 
} 

Usando async, puede escribir el mismo código como este:

void async DoAsyncStuff() 
{ 
    int res = await FooAsync(); 
    DoSomethingWithInt(res); 
} 

El el resultado es el mismo La palabra clave await convierte el resto de su método en una continuación que se reanuda después de que FooAsync produzca un valor. Es como tu otro código, pero más fácil de leer. * shrug *

+0

Su método 'async' realmente no debería t estar vacío volviendo. Los métodos 'async' solo deben ser devueltos cuando serán un manejador de un evento. Debería devolver 'Tarea' si no hay un valor de retorno en el método. Aparte de eso, la publicación lo suficientemente decente. – Servy

+0

@Servy "los métodos asíncronos solo deben anularse cuando sean controladores de un evento". Ese es el caso aquí, ¿verdad? ¿Qué debería devolver 'DoAsyncStuff' en este ejemplo, y dónde obtendría ese valor sin escribir código superfluo? Además, si un método async devuelve Task y * no * lo espera, recibirá una advertencia de compilación (CS4014), que es molesto. Recientemente [pregunté sobre ese tema] (http://stackoverflow.com/questions/14903887/warning-this-call-is-not-awaited-execution-of-the-current-method-continues) aquí. Si tiene una mejor respuesta, ¿podría publicarla allí? – Mud

+0

Cuando un método 'async' devuelve vacío, esencialmente lo convierte en un método de" fuego y olvídate ". La persona que llama no tiene manera de saber cuándo el método realmente termina. No hay ninguna indicación del código OP aquí que eso es lo que él quiere. En cuanto a la advertencia del compilador, es porque casi seguro * no quieres hacer eso *, como te dije en la publicación a la que te vinculaste; la advertencia es * correctamente * lo que indica que hay un defecto en su diseño, y que las probabilidades indican que no desea el comportamiento que está recibiendo. Si bien es posible que desee ese comportamiento en algunos casos extremos, estoy de acuerdo con mis afirmaciones. – Servy

Cuestiones relacionadas