Extensions
Extensions
Extensions return ITaskScheduler decorators. They do not own or dispose the scheduler or flow they wrap. Keep the underlying ITaskFlow reference and dispose it at the owner boundary.
| Extension | Package and frameworks | Effect | Details |
|---|---|---|---|
CreateCancelPrevious |
TaskFlow; all targets |
Cancels older unfinished submissions | Cancellation |
CreateCancellationScope |
TaskFlow; all targets |
Links a shared lifetime token | Cancellation |
WithTimeout |
TaskFlow; all targets |
Adds a queue-and-execution timeout | Reliability |
WithThrottle |
TaskFlow on .NET 8/10; TaskFlow.Extensions.Time on netstandard2.0 |
Rejects submissions inside an admission interval | Reliability |
OnError |
TaskFlow; all targets |
Observes matching failures and rethrows | Reliability |
WithOperationName |
TaskFlow; all targets |
Adds an operation-name annotation | Observability |
Intercept |
TaskFlow; all targets |
Runs synchronous or asynchronous lifecycle callbacks | Observability |
WithLogging |
TaskFlow.Microsoft.Extensions.Logging; all targets |
Emits structured lifecycle events | Observability |
Composition
Decorator order is observable. The last extension call produces the outermost scheduler and sees a submission first.
await using var flow = new TaskFlow();
ITaskScheduler operations = flow
.WithLogging(logger)
.WithTimeout(TimeSpan.FromSeconds(10))
.CreateCancellationScope(lifetimeToken)
.WithOperationName("orders.persist");
await operations.Enqueue(token => PersistAsync(token));
Here the operation-name annotation travels inward to timeout and logging. The caller token, lifetime token, timeout signal, and flow-disposal token can all request cancellation. The delegate must cooperate with the token it receives.
static Task PersistAsync(CancellationToken token) => Task.CompletedTask;
Common rules
- Await or return an operation task when its outcome matters to the caller. For intentional fire-and-forget work, discard it explicitly and add failure reporting inside the operation or through a decorator when needed.
- Dispose the underlying flow, not its decorators.
- Treat cancellation as a request rather than proof that work stopped.
- Use named local functions for value-returning asynchronous delegates if overload resolution is ambiguous.
- Test policy ordering because moving one decorator can change which annotations or failures another decorator observes.