Continuations
- A continuation task (continuation) is an async task that is invoked by another task (the antecedent) when the antecedent finishes.
- Continuations allow descendant operations to consume the results of an ancestor. In this way, you can chain tasks.
- A continuation is created in the WaitingForActivation state and activated automatically when its antecedent task completes.
Blocking
Continuations, like any Task, do not block the current thread.
To block until a continuation finishes, call Task.Wait
.
Do Not Call Task.Start on a Continuation
This will result in an InvalidOperationException
.
Creating a Continuation for a Single Antecedent
Use Task.ContinueWith
:
public class SimpleExample
{
public static async Task Main()
{
// Declare, assign, and start the antecedent task.
Task<DayOfWeek> taskA = Task.Run(() => DateTime.Today.DayOfWeek);
// Execute the continuation when the antecedent finishes.
var continuation = taskA.ContinueWith(antecedent => Console.WriteLine($"Today is {antecedent.Result}."));
await continuation;
}
}
Passing Data
If the antecedent user delegate is a Task<TResult>
and it completed, then the continuation can access the Task<TResult>.Result
property of the antecedent. However, if the antecedent was canceled or faulted, this will throw an exception. To avoid this, use TaskContinuationOptions.OnlyOnRanToCompletion
:
await taskA.ContinueWith(antecedent =>
{
Console.WriteLine($"Today is {antecedent.Result}.")
},
Otherwise, guard against the exception.
Creating a Continuation for Multiple Antecedents
Use Task.WhenAll
or Task.WhenAny
against a collection of Tasks.
TaskContinuationOptions
Task.ContinueWith
has an overload that accepts a TaskContinuationOptions
instance.
Canceling a Continuation
A continuation is canceled when:
- It receives a cancellation request and throws an
OperationCanceledException
(like any Task) - The continuation is passed a
CancellationToken
whoseIsCancellationRequested
property is already true. - The continuation never runs because a condition set by its
TaskContinuationOptions
was not met.
Exceptions
Exceptions thrown in continuations are not propagated back to the antecedent. Handle them as you would in any other task.