C# › Asynchronous Programming

How do you correctly implement a producer-consumer pattern using System.Threading.Channels for asynchronous data pipelines?

Advanced

Answer

Channel<T> provides a thread-safe, fully asynchronous queue with separate Writer and Reader handles — a producer calls writer.WriteAsync() (or TryWrite) to add items, and a consumer uses 'await foreach' over reader.ReadAllAsync() to process them as they arrive, with built-in backpressure support when the channel has a bounded capacity.
var channel = Channel.CreateBounded<int>(capacity: 100);

// Producer
_ = Task.Run(async () => {
  for (int i = 0; i < 1000; i++) await channel.Writer.WriteAsync(i);
  channel.Writer.Complete();
});

// Consumer
await foreach (var item in channel.Reader.ReadAllAsync()) {
  Console.WriteLine(item);
}
Real-world example Building a bounded, backpressure-aware pipeline where a fast producer (like a file reader) shouldn't overwhelm a slower consumer (like a database writer).

Common follow-ups: How does a BOUNDED channel's WriteAsync() behave differently from an unbounded one when the channel is full?