CodeBlanks Logo Icon CodeBlanks

Project design

C# course · Expert · Lesson 43/47

Design the skeleton of the expert final mini app.

Project design

In this project you will build a parallel log processor: zero-copy level parsing with Span<T>, a producer-consumer flow with Channel, a source generator simulation for DTOs, and multi-threaded counting with Parallel.ForEach.

All pieces live in one static class LogProcessor. Each lesson adds one piece; the initial code includes the previous lesson's solution. The final lesson ties everything together.

LogProcessor skeleton

The skeleton holds two methods: ParseLevel and CountByLevel. ParseLevel maps a level name (INFO, WARN, ERROR) to an integer code. CountByLevel counts how many logs in an array have a given level.

This base will be extended with Span, Channel, and a source generator in later lessons. Each piece builds on the previous one.

Exercise Write the LogProcessor skeleton

Add two methods to the LogProcessor static class. public static int ParseLevel(string level): use a switch with "INFO" => 0, "WARN" => 1, "ERROR" => 2, _ => -1. public static int CountByLevel(string[] logs, int targetLevel): with foreach, find each log's level with ParseLevel(log.Split(':')[0]) and count. In Main, define logs as { "INFO: a", "WARN: b", "INFO: c", "ERROR: d" } and print CountByLevel(logs, 0).

Show example solution
var logs = new[] { "INFO: a", "WARN: b", "INFO: c", "ERROR: d" }; Console.WriteLine(LogProcessor.CountByLevel(logs, 0));
Example solution:
using System;

static class LogProcessor
{
    public static int ParseLevel(string level)
    {
        return level switch
        {
            "INFO" => 0,
            "WARN" => 1,
            "ERROR" => 2,
            _ => -1
        };
    }

    public static int CountByLevel(string[] logs, int targetLevel)
    {
        int count = 0;
        foreach (var log in logs)
        {
            if (ParseLevel(log.Split(':')[0]) == targetLevel)
            {
                count++;
            }
        }
        return count;
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine("LogProcessor skeleton ready");
        var logs = new[] { "INFO: a", "WARN: b", "INFO: c", "ERROR: d" };
        Console.WriteLine(LogProcessor.CountByLevel(logs, 0));
    }
}

Test yourself

  1. Which component is used to process logs in parallel in this project?

    • Channel (producer-consumer)
    • ArrayList
    • DataTable
    • StringBuilder
    Show answer

    Channel (producer-consumer) — Correct. Channel is used for the producer-consumer flow.

  2. Complete the ParseLevel declaration

    public static int ____(string level)
    Show answer
    public static int ParseLevel(string level)
  3. Match each project component

    Span<T>
    Low-copy memory view
    Channel<T>
    Producer-consumer channel
    unsafe
    Pointer-based low-level access

All lessons in Expert