liveBook · Manning

Channel<T>

As explained in C# Concurrency: Asynchronous and multithreaded programming

Channel<T> is a .NET asynchronous producer-consumer communication type for exchanging values between writers and readers.

Channel<T> provides an ordered, thread-safe queue for asynchronous communication between multiple producers and consumers. Writers add messages through the channel writer, while readers await values through the channel reader. A worker can run with Task.Run, reach await, and release its thread-pool thread instead of blocking it. Consumers use an asynchronous read loop and catch ChannelClosedException to detect completion. section 13.2.3

Listing 13.12 Async background processing with Channel<T>
var ch = Channel.CreateUnbounded<int>();
Task[] tasks = new Task[10];
for(int i=0; i<10;++i)                                       #1
{
   var threadNumber = i;
   tasks[i] = Task.Run(async () =>
   {
      var rng = new Random((int)threadNumber);
      int count = 0;
      while (true)
      {
         try
         {
            var currentValue = await ch.Reader.ReadAsync();  #2
            Console.WriteLine($"task {threadNumber} value {currentValue}");
            Thread.Sleep(rng.Next(500));
            count++;
         } 
         catch(ChannelClosedException)                       #3
         {
            break;
         }
      }
      Console.WriteLine($"task {threadNumber}, total {count} items");
   });
}
for (int i = 0; i < 100; i++)                                #4
{
   await ch.Writer.WriteAsync(i);
}
ch.Writer.Complete();                                        #5
Task.WaitAll(tasks);                                         #6

A runnable pattern creates an unbounded integer channel, starts ten asynchronous consumers, writes 100 values, and reports each worker’s processed count. section 13.2.3

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Defines ordered thread-safe queues and demonstrates asynchronous reads, writes, task-pool execution, and closure detection.
Examples
Demonstrates ten tasks consuming 100 integers from an unbounded channel while reporting processing totals.
What it assumes
Assumes familiarity with asynchronous C# code, tasks, await, and producer-consumer workflows.
What you can do after
Apply via Channel<T> to coordinate asynchronous background workers and handle channel closure.
How it connects
Connects producer-consumer scenarios with BlockingCollection<T>, Task.Run, await, and thread-pool execution.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C# Concurrency: Asynchronous and multithreaded programming. The section links point to the parts of the book it draws on.