MexDev
MexDev

Reputation: 231

Lock dictionary within same thread

I have a function that returns an entry on a dictionary, based on the Key (name) and if it doesn't exist, returns a newly created one.

The question I have is with the "double lock" : SomeFunction locks the _dictionary, to check for the existance of the key, then calls a function that also locks the same dictionary, it seems to work but I am not sure if there is a potential problem with this approach.

public Machine SomeFunction(string name) 
{
    lock (_dictionary)
    {
        if (!_dictionary.ContainsKey(name))
                    return CreateMachine(name);
        return _dictionary[name];
    }
}


private Machine CreateMachine(string name)
{
    MachineSetup ms = new Machine(name);
    lock(_dictionary)
    {
        _ictionary.Add(name, ms);
    }
    return vm;
}

Upvotes: 10

Views: 2264

Answers (3)

Joe Healy
Joe Healy

Reputation: 5817

New since .net 4.0, check out the ConcurrentDictionary - ConcurrentDictionary is a thread-safe collection of key/value pairs that can be accessed by multiple threads concurrently. More info at https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx .

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942348

No problem here, the lock is re-entrant by the same thread. Not all sync objects have thread affinity, Semaphore for example. But Mutex and Monitor (lock) are fine.

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1503489

That's guaranteed to work - locks are recursive in .NET. Whether it's really a good idea or not is a different matter... how about this instead:

public Machine SomeFunction(string name) 
{ 
    lock (_dictionary)
    {
        Machine result;
        if (!_dictionary.TryGetValue(name, out result))
        {
            result = CreateMachine(name);
            _dictionary[name] = result;
        }
        return result;
    } 
}

// This is now *just* responsible for creating the machine,
// not for maintaining the dictionary. The dictionary manipulation
// is confined to the above method.
private Machine CreateMachine(string name)
{
    return new Machine(name);
}

Upvotes: 10

Related Questions