Continuing a Task<T> to a Task<U> without blocking on Result

Viewed 726

I have two asynchronous methods Task<int> DoInt() and Task<string> DoString(int value). I have a third asynchronous method Task<string> DoBoth(int value) whose goal is to asynchronously execute DoInt(), piping it's output to DoString(int) and having the result be the result of DoBoth().

The important constraints are:

  1. I may not have source code to DoInt() or DoString(), so I can't modify them.
  2. I don't want to block at any point
  3. Output (result) of one task must be passed as input to the next
  4. The final output (result) is what I want to be the result of DoBoth()

The key being I already have methods that are asynchronous (i.e. return Task) and I want to pipe data from task to task, without blocking along the way, returning the final result in the initial task. I can do all the following except not blocking in the following code:

Code example:

// 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; 
    });
}

Since Task<string> DoString(int) is already an asynchronous method, how do I cleanly create a non-blocking continuation to it? Effectively I want to create a continuation from an existing Task and not from a Func.

2 Answers
Related