×

c# · level 3 · unit 7 · lesson 2

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

A lets many threads count together.

A plain Dictionary is not : two threads adding at once can corrupt it. ConcurrentDictionary<TKey, TValue> is built for sharing, and each of its methods does its whole job in one safe step.

Counting from many threads hides a trap called : checking for a key, then adding it, leaves a gap between the two steps. AddOrUpdate(colour, 1, (key, old) => old + 1) closes the gap. It adds 1 for a new key or updates the old count, all in one step.

Its entries come out in no fixed order, so sort them before printing.

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;

string[] lines = { "red blue red", "blue green", "red green green" };
var counts = new ConcurrentDictionary<string, int>();
var jobs = lines.Select(line => Task.Run(() =>
{
    foreach (string colour in line.Split(' '))
    {
        counts.AddOrUpdate(colour, 1, (key, old) => old + 1);
    }
}));
await Task.WhenAll(jobs);
foreach (var pair in counts.OrderBy(p => p.Key))
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

counts.OrderBy(p => p.Key) sorts the entries by key, so the report reads the same every run.