2011-11-23 6 views
39

Después de this question, estoy tratando de implementar un método asíncrono utilizando el TPL, y tratando de seguir las pautas de TAP.Dónde definir la devolución de llamada para el método asíncrono basado en tareas

Quiero que mi método asíncrono realice una devolución de llamada cuando haya terminado. Por lo que puedo ver, hay tres formas en que puedo hacer esto.

1) Devolución de llamada manualmente en mi tarea delegada

public Task DoWorkAsync(DoWorkCompletedCallback completedCallback) 
{ 
    return Task.Factory.StartNew(
    { 
     //do work 

     //call callback manually 
     completedCallback(); 
    }); 
} 

2) Asignar devolución de llamada a la tarea de delegado tarea

public Task DoWorkAsync(DoWorkCompletedCallback completedCallback) 
{ 
    return Task.Factory.StartNew(
    { 
     //do work 
    } 
    ).ContinueWith(completedCallback); //assign callback to Task 
} 

3) Asignación de devolución de llamada a la tarea de la persona que llama

public Task DoWorkAsync() 
{ 
    return Task.Factory.StartNew(
    { 
     //do work 
    }); 
} 

public void SomeClientCode() 
{ 
    Task doingWork = DoWorkAsync(); 
    doingWork.ContinueWith(OnWorkCompleted); 
} 

Mi intuición es que 3 es más correcto, porque desacopla la devolución de llamada del método, y significa que el cliente el código puede administrar la tarea de la forma que considere adecuada (utilizando devoluciones de llamada, sondeos, etc.), que parece ser de lo que se tratan las Tareas. Sin embargo, ¿qué sucede si DoWorkAsync() completa su trabajo antes de que el código del cliente conecte su devolución de llamada?

¿Existe una forma generalmente aceptada de hacer esto o es demasiado nuevo?

¿Hay alguna ventaja de hacer 2) más de 1)?

Respuesta

28

La forma generalmente aceptada es 3.

Los usuarios de TPL generalmente saben que pueden seguir una tarea con ContinueWith. 1 y 2 proporcionan la misma funcionalidad, pero con una interfaz no estándar; el usuario debe descubrir qué significa el parámetro de delegado y qué debe pasar, p. si no quieren continuar, todo eso mientras el método todavía devuelve una Tarea que puede continuarse de la manera estándar.

+4

Gracias, eso tiene sentido. Irá con 3. ¿Pero qué sucede si la tarea se completa antes de que se adjunte el delegado de continuar? ¿Todavía se llama? Estoy encontrando los documentos un poco vagos. – GazTheDestroyer

+3

Sí, se llama. – dtb

+0

Tengo una pregunta para el ejemplo 3. Si SomeClientCode() se está ejecutando en el subproceso ui (WPF), ¿OnWorkCompleted también estará en el subproceso ui? ¿O el mismo hilo que hizo el trabajo asincrónico? –

Cuestiones relacionadas