HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

An extension method to safely retrieve or add a dictionary value

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodvalueextensiondictionaryretrievesafelyadd

Problem

The extension method:

/// 
/// Thread safe. May lock on the input dictionary.
/// 
public static U GetOrAdd(this Dictionary dict, T key, Func create) {
    U val;
    if (!dict.TryGetValue(key, out val)) {
        lock (dict) {
            if (!dict.ContainsKey(key)) {
                val = create();
                dict[key] = val;
            } else {
                val = dict[key];
            }
        }
    }
    return val;
}


Sample usage:

var idVals = new Dictionary>();
List vals = idVals.GetOrAdd(id, () => new List());
vals.Add(3);


Explanation:

  • If the key exists, we quickly retrieve the value using the


TryGetValue() method

  • If the key doesn't exist we use the provided create delegate to make a new one



  • We are protected against the case of two threads simultaneously looking for a key that doesn't exist by locking on the input


dictionary and afterward re-checking to see if the key still doesn't exist

Questions:

  • Are there scenarios that will cause this fail?



  • I found this extension method to be useful, but is clear enough to be properly understood by others?



  • Are there easier ways to achieve the thread-safety I'm looking for?



  • I know it's considered dangerous and bad practice to lock on an input parameter, but can I rely on the fact that locking on a dictionary to safely add/remove elements is a common convention?

Solution

Are there easier ways to achieve the thread-safety I'm looking for?

Yes, use the ConcurrentDictionary Class which is avaible since NET 4.0

Context

StackExchange Code Review Q#65089, answer score: 7

Revisions (0)

No revisions yet.