Thread safe changes to a ConcurrentDictionary

I am populating a ConcurrentDictionary in a Parallel.ForEach loop:

var result = new ConcurrentDictionary<int, ItemCollection>();

Parallel.ForEach(allRoutes, route => 
{
    // Some heavy operations

    lock(result)
    {
        if (!result.ContainsKey(someKey))
        {
            result[someKey] = new ItemCollection();
        }

        result[someKey].Add(newItem);
    }
}

How do I perform the last steps in a thread-safe manner without using the lock statement?

EDIT: Assume that ItemCollection is thread-safe.

Jon Skeet
people
quotationmark

I think you want GetOrAdd, which is explicitly designed to either fetch an existing item, or add a new one if there's no entry for the given key.

var collection = result.GetOrAdd(someKey, _ => new ItemCollection());
collection.Add(newItem);

As noted in the question comments, this assumes that ItemCollection is thread-safe.

people

See more on this question at Stackoverflow