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.

Source and packages