Abstract [ Documentation]
The Task Asynchronous Pattern is a different pattern for using tasks, async, and await than the pattern described in notes on asynchronous programming.
The TAP pattern uses Task and Task<T> objects which model asynchronous operations. Generally:
- For I/O-bound code,
awaitaTaskorTask<T>in async method. - For CPU-bound code, await an operation that is started on a background thread via
Task.Run.
The TAP pattern uses a single method to represent the initiation and completion of an asynchronous operation (unlike EAP (Begin and End) and APM (IAsyncResult)).
cancellation
In TAP, cancellation is optional for both async method implementers and consumers:
- Operations that may be canceled should expose an overload that accepts a
CancellationToken. - Operations that cannot be canceled should not expose this overload.
- Consumer code that does not require cancellation but calls a method that exposes a cancellation token should pass a
CancellationToken.None.
If an implemented cancellation token is signaled:
- Decision: Honor cancellation?
- Yes
- Return a
Canceledstate task; any code awaiting this task will receive anOperationCanceledException - Continuations scheduled?
- Yes
- ContinuationOption NotOnCanceled set?
- Yes: continuations end.
- No: continuations proceed
- ContinuationOption NotOnCanceled set?
- Yes
- Return a
- No
- Result produced?
- Yes: return a
RanToCompletionstate task - No: return a
Faultedstate task
- Yes: return a
- Result produced?
- Yes
progress reporting
In TAP, progress is handled through the IProgress<T> object passed to an async method as a parameter (usually named progress).
The type of T depends on the use case. A ReadAsync method may want to report the number of bytes read (as a long):
public Task ReadAsync(byte[] buffer, int offset, int count, IProgress<long> progress)
Progress reporting can be accomplished through the Progress<T> class which implements IProgress<T>. Progress<T> exposes a ProgressChanged event
that is raised every time the async operation reports a progress update. Register a handler for this event, or pass a single handler to the Progress<T> constructor.