Phase 23 of 30 · Topic 23.3

Multi-Producer Multi-Consumer (MPMC) Pipeline Architecture

1Concept

Channels support multiple concurrent background producer tasks and multiple concurrent worker consumer tasks, distributing workloads with automatic load balancing.

2Architecture Diagram

[ Producer 1 ] ──┐                                  ┌──> [ Worker Consumer 1 ]
[ Producer 2 ] ──┼──> [ Bounded Channel Buffer ] ───┼──> [ Worker Consumer 2 ]
[ Producer 3 ] ──┘                                  └──> [ Worker Consumer 3 ]

3Code Example

C# 13 & .NET 9
using System;
using System.Threading.Channels;
using System.Threading.Tasks;

public class MpmcChannelDemo
{
    public static async Task Main()
    {
        var channel = Channel.CreateBounded<int>(100);

        // Spawn 2 Consumers
        var consumer1 = Task.Run(async () =>
        {
            await foreach (var item in channel.Reader.ReadAllAsync())
            {
                Console.WriteLine($"[Consumer A] Processed #{item}");
            }
        });

        var consumer2 = Task.Run(async () =>
        {
            await foreach (var item in channel.Reader.ReadAllAsync())
            {
                Console.WriteLine($"[Consumer B] Processed #{item}");
            }
        });

        // Producer pushes items
        for (int i = 1; i <= 4; i++)
        {
            await channel.Writer.WriteAsync(i);
        }
        channel.Writer.Complete();

        await Task.WhenAll(consumer1, consumer2);
    }
}

4Expected Output

[Consumer A] Processed #1
[Consumer B] Processed #2
[Consumer A] Processed #3
[Consumer B] Processed #4

5Key Takeaways

  • Channels automatically load-balance items across all active reader threads.
  • Thread-safe without manual mutex locks.
  • Ideal for background background task queues in ASP.NET Core.