ConcurrentDictionary over List 2

Doing it wrong again

In the previous post, I have shown why the following type can be dangerous:

ConcurrentDictionary<string, List<int>>

The problem starts when we have multiple threads using (writing and reading) this dictionary at the same time. To avoid state corruption, we need to control this access by making it thread-safe.

In the tests there was a thread adding new items to the list on a given key, and on thread was enumerating the values. Running the application caused an exception to happen.

In this post though, I will simply run two threads adding items to the same list. Both threads will add 50000 items, which would result 99999 (the very first TestAdd invocation only creates the list) items when both finished execution. Note, that I will use the very same NonConcurrent example as described in the previous post.

public static async Task Main(string[] args)
{
  const int Interations = 50000;
  var test = new NonConcurrent();
  var taskAddA = Task.Run(() =>
  {
    int i = 0;
    while(i++ < Interations)
    {
      test.TestAdd();
    }
  });
  var taskAddB = Task.Run(() =>
  {
    int i = 0;
    while(i++ < Interations)
    {
      test.TestAdd();
    }
  })
  await Task.WhenAll(taskAddA, taskAddB);
  test._data.TryGetValue("key", out var mylist);
  Console.WriteLine($"Count: {mylist.Count()}, Ellapsed: {sw.ElapsedMilliseconds}");
}

When running this application we do not get the exception, though when we observer the results, we see that instead of having 99999 items in the list, we only have less, in my test run 99437. Having the application running the parallel threads longer will increase the items missed from the list, while for only a couple of items, there is a good chance we get all the items. Hence it is difficult to catch the error.

Next

In the coming posts, will investigate several different solution on solving this issue, and measure their performance characteristics.