TaskFlow for .NET
TaskFlow is an owned FIFO execution lane for asynchronous .NET work. Each submitted operation gets its own result task while the lane serializes access, preserves submission order, and provides a clear shutdown boundary.
Use TaskFlow to:
- serialize calls to mutable or non-thread-safe resources;
- turn synchronous callbacks into ordered asynchronous processing;
- bind background work to a component or dependency-injection scope;
- cancel obsolete work when a newer operation arrives;
- compose timeout, cancellation, logging, annotations, and error observation; and
- run work on the thread pool, a dedicated thread, or a caller-owned thread.
Start by goal
| Goal | Read |
|---|---|
| Decide whether TaskFlow is the right primitive for this problem | Choosing TaskFlow |
| Create and dispose a first FIFO lane | Getting started |
| Understand operation completion and ownership | Concepts and lifecycle |
| Avoid cancellation, timeout, and disposal surprises | Semantics and pitfalls |
| Choose the thread pool, a dedicated thread, or another scheduler | Execution models |
| Apply TaskFlow to common application problems | Recipes |
| Add cancellation, reliability, and diagnostics policies | Extensions |
| Register scoped or named flows | Dependency injection |
| Implement adapters or custom flows | Customization |
| Check framework and package availability | Compatibility |
| Diagnose common integration problems | Troubleshooting |
Install
dotnet add package TaskFlow
using System.Threading.Tasks.Flow;
await using var flow = new TaskFlow();
Task first = flow.Enqueue(async token =>
{
await Task.Delay(25, token);
Console.WriteLine("first");
});
Task second = flow.Enqueue(token =>
{
Console.WriteLine("second");
return Task.CompletedTask;
});
await Task.WhenAll(first, second);
second starts only after first completes. A failure in one returned task does not stop later queued operations.