.NET › Background Services
What are common patterns for implementing a producer-consumer background processing pipeline using Channel<T> with a BackgroundService?
AdvancedAnswer
System.Threading.Channels provides Channel<T>, a high-performance, thread-safe async queue -- a producer (e.g., an API endpoint) writes items via ChannelWriter.WriteAsync, while a BackgroundService acts as the consumer, reading items via ChannelReader.ReadAllAsync in a loop, decoupling request-handling latency from background processing time while providing built-in backpressure if the channel has bounded capacity.
var channel = Channel.CreateBounded<EmailMessage>(capacity: 100);
builder.Services.AddSingleton(channel.Writer);
builder.Services.AddSingleton(channel.Reader);
builder.Services.AddHostedService<EmailSenderService>();
public class EmailSenderService : BackgroundService {
protected override async Task ExecuteAsync(CancellationToken ct) {
await foreach (var message in _reader.ReadAllAsync(ct)) {
await SendEmailAsync(message);
}
}
}Real-world example An API endpoint accepting bulk email requests writes each email to a bounded Channel and returns immediately (202 Accepted), while a background service consumes and actually sends the emails, keeping the API responsive under heavy load.