Creating a continuation Task that has a result of different type than the first task, with ContinueWith, is not trivial. You have to use the Unwrap method in order to flatten the resulting Task<Task<MySecondResult>>, handle carefully the failure and cancellation cases, and specify explicitly the TaskScheduler that will execute the continuation:
Task<MySecondResult> task = GetFirstResultAsync().ContinueWith(t =>
{
if (t.IsFaulted)
{
var tcs = new TaskCompletionSource<MySecondResult>();
tcs.SetException(t.Exception.InnerExceptions);
return tcs.Task;
}
if (t.IsCanceled)
{
TaskCompletionSource<MySecondResult> tcs = new();
tcs.SetCanceled(new TaskCanceledException(t).CancellationToken);
return tcs.Task;
}
return GetSecondResultAsync(t.Result);
}, TaskScheduler.Default).Unwrap();
This is quite cumbersome. You don't want to have code like this appear frequently in your application code. You can either encapsulate this functionality in an extension method, like the Then/ContinueWithResult extension method requested in this GitHub proposal, or use async/await instead of the ContinueWith. Async/await is composable, so you can write a third async method that combines the GetFirstResultAsync and the GetSecondResultAsync to one:
async Task<MySecondResult> GetSecondAfterFirstAsync()
{
MyFirstResult result = await GetFirstResultAsync();
return await GetSecondResultAsync(result);
}