Tengo dos métodos asincrónicos Task<int> DoInt()
y Task<string> DoString(int value)
. Tengo un tercer método asincrónico Task<string> DoBoth(int value)
cuyo objetivo es ejecutar de forma asincrónica DoInt()
, la salida de la tubería es DoString(int)
y el resultado es el resultado de DoBoth()
.Continuación de una tarea <T> en una tarea <U> sin bloqueo en el resultado
Las limitaciones importantes son:
- Puede que no tenga el código fuente a
DoInt()
oDoString()
, así que no puedo modificarlos. - no quiero bloquear en cualquier punto
- salida (resultado) de una tarea debe ser pasado como entrada a la siguiente
- La salida final (resultado) es lo que yo quiero ser el resultado de
DoBoth()
La clave es que ya tengo métodos que son asíncronos (es decir, devolver tarea) y quiero canalizar datos de tarea a tarea, sin bloquear en el camino, devolviendo el resultado final en la tarea inicial. Puedo hacer todo lo siguiente, excepto no bloquear en el siguiente código:
Código ejemplo:
// Two asynchronous methods from another library, i.e. can't be changed
Task<int> DoInt();
Task<string> DoString(int value);
Task<string> DoBoth()
{
return DoInt().ContinueWith<string>(intTask =>
{
// Don't want to block here on DoString().Result
return DoString(intTask.Result).Result;
});
}
Desde Task<string> DoString(int)
ya es un método asíncrono, ¿cómo puedo crear una continuación limpiamente sin bloqueo a ella? De hecho, quiero crear una continuación de una Tarea existente y no de una Func.
¿'DoInt' toma un int como argumento, o no? Lo tiene en ambos sentidos en su publicación ... –
@ReedCopsey - He arreglado la firma para DoInt(). Si tiene un parámetro o no, no es importante en el ejemplo, pero la inconsistencia en mi ejemplo es confusa :) También renombré valueTask => intTask para mayor claridad. – MikeJansen