2012-08-23 19 views
37

que estoy tratando de envolver mi cabeza alrededor de la TPL, los nuevos async/await características en C# 5, y los misterios de TaskCompletionSource.TaskCompletionSource: Cuándo utilizar SetResult() frente TrySetResult(), etc

Una cosa que no me queda claro es cuándo usar SetResult, SetException, y SetCancel frente TrySetResult, TrySetException y TrySetCancel.

Esto es lo que tiene que decir MSDN:

Esta operación devolverá false si la tarea ya está en uno de los tres estados finales: RanToCompletion, con fallo o Cancelado.

Este método también devuelve falso si la tarea subyacente tiene ya se ha eliminado.

Ok, entiendo eso, pero en realidad no ofrece ninguna orientación sobre cuándo o por qué utilizar uno sobre el otro.

Entonces, ¿cuál es el problema?

Respuesta

46

I sospechoso el punto es que si sólo hay una cosa que se ponía el resultado, simplemente llame SetResult etc. Si usted termina llamando SetResult dos veces, que indica un error. (Del mismo modo si se ha eliminado el TaskCompletionSource)

Si tiene varios hilos que podrían estar intentando establecer el resultado al mismo tiempo (por ejemplo, está allí para indicar el primer resultado de varias llamadas de servicio web paralelas) luego use TrySetResult, ya que es completamente razonable que varios hilos "intenten" establecer el resultado, sin saber si otro hilo ya lo ha configurado.

No he visto ninguna orientación oficial al respecto, pero eso tendría sentido.

+8

es decir, realmente, la única razón por la que necesitaría llamar a 'TrySetResult' es si establece el resultado más de una vez. 'SetResult'" completa "la' Tarea' asociada, por lo que llamar 'SetResult' de nuevo intentará establecer el resultado' Task 'después de que la tarea se haya completado. (Bloques 'SetResult' hasta que' Task' se complete, al igual que 'TrySetResult') Si solo llamas a' SetResult' una vez, entonces nunca deberías 'TrySetResult'. FWIW. 'Cadenas de SetResult' a' TrySetResult' ... –

+0

¡Gracias chicos, tienes mucho sentido! – HolySamosa

+0

También tenga en cuenta que SetResult devuelve 'void' mientras TrySetResult devuelve' bool', por lo que si desea hacer algo de manera condicional en función del estado de la tarea, entonces 'TrySetResult' se comprueba y establece al mismo tiempo (¿atómicamente?). – chakrit

Cuestiones relacionadas