Заблокировать словарь в пределах одной темы

У меня есть функция, которая возвращает запись в словаре на основе ключа (name), а если она не существует, возвращает вновь созданный.

У меня есть вопрос с "двойной блокировкой": SomeFunction блокирует _dictionary, чтобы проверить наличие ключа, затем вызывает функцию, которая также блокирует тот же словарь, кажется, работает, но я не уверен, что существует потенциальная проблема с этим подходом.

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;
}

Ответ 1

Что гарантировано для работы - блокировки являются рекурсивными в .NET. Действительно ли это хорошая идея или нет - это другое дело... как об этом:

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);
}

Ответ 2

Здесь нет проблем, блокировка повторится одним и тем же потоком. Не все объекты синхронизации имеют сходство потоков, например Семафор. Но Mutex и Monitor (lock) в порядке.

Ответ 3

Новый с .net 4.0, проверьте ConcurrentDictionary - ConcurrentDictionary - это потокобезопасная коллекция пар ключ/значение, к которой можно одновременно обращаться несколькими потоками. Дополнительная информация на https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx.