C#
Summary - Channels
Combine ChannelWriter, ChannelReader and Complete to write a log processor.
Summary - Channels
In this summary you will write a log processor. The producer writes log lines into the channel and closes it with Complete; the consumer reads each log with ReadAllAsync, splits by level and counts.
The methods from earlier lessons (CreateUnbounded, WriteAsync, Complete, ReadAllAsync and OrderBy) all come together here. A single-threaded async flow keeps the output deterministic.
Log processor design
The producer writes three logs: "INFO: started", "WARN: slow", "ERROR: fail". Then Complete is called. The consumer reads each log with await foreach, extracts the level name with Split(':')[0] and counts in a Dictionary.
Results are printed alphabetically with OrderBy(k => k.Key). Since the levels differ, each count is 1.
Exercise Assemble the log processor
channel is an unbounded string channel. Write three logs with await channel.Writer.WriteAsync: "INFO: started", "WARN: slow", "ERROR: fail". Call channel.Writer.Complete(). In a Dictionary<string, int>, count each log's level (log.Split(':')[0]) with await foreach (var log in channel.Reader.ReadAllAsync()). Then print $"{kvp.Key}: {kvp.Value}" sorted by OrderBy(k => k.Key). Make Main async Task.
Show example solution
')[0]] = counts.GetValueOrDefault(...) + 1. Print with OrderBy(k => k.Key).
Example solution:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var channel = Channel.CreateUnbounded<string>();
var counts = new Dictionary<string, int>();
await channel.Writer.WriteAsync("INFO: started");
await channel.Writer.WriteAsync("WARN: slow");
await channel.Writer.WriteAsync("ERROR: fail");
channel.Writer.Complete();
await foreach (var log in channel.Reader.ReadAllAsync())
{
var level = log.Split(':')[0];
counts[level] = counts.GetValueOrDefault(level) + 1;
}
foreach (var kvp in counts.OrderBy(k => k.Key))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
}
}
Test yourself
-
Complete the WriteAsync call
await channel.Writer.____;
Show answer
await channel.Writer.WriteAsync("log: error");
-
What does the producer do in a log processor?
- Reads logs
- Filters logs
- Writes logs to the channel
- Deletes logs
Show answer
Writes logs to the channel — Correct. The producer writes logs with WriteAsync.
-
Match each log processor step
- CreateUnbounded
- Create the channel
- Writer.WriteAsync
- Produce a log
- Writer.Complete
- End production
- Reader.ReadAllAsync
- Consume logs
Next lesson: What are source generators?