I suspect that both your problems would be resolved if you use the Unwrap
extension method. Your goal is to return a new task as a result of your continuation function; however, since the continuation itself is executed as a task, this would lead to an extra level of nesting (task returning task). Thus, you need to eliminate this nesting using Unwrap
, which will give you a proxy task that is bound to the result of the inner task.
WebRequest request = HttpWebRequest.Create(uri);
Task<WebResponse> responseTask = request.GetResponseAsync(cancellationToken);
Func<Task<WebResponse>, Task<WebResponse> continuation =
task =>
{
WebRequest followup = HttpWebRequest.Create(uri2);
return followup.GetResponseAsync(cancellationToken);
};
Task<Task<WebResponse>> finalResultTask = responseTask.ContinueWith(continuation);
Task<WebResponse> proxyTask = finalResultTask.Unwrap();
Quick optimization: Since your continuation function does little other than spawn off a new task through GetResponseAsync
, you can reduce its execution overhead by specifying it as ExecuteSynchronously
:
Task<Task<WebResponse>> finalResultTask = responseTask.ContinueWith(continuation,
TaskContinuationOptions.ExecuteSynchronously);
Edit: Per Servy's suggestion, you should pass your CancellationToken
to your continuation function too:
Task<Task<WebResponse>> finalResultTask = responseTask.ContinueWith(continuation,
cancellationToken,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Current);