Заблокировать словарь в пределах одной темы
У меня есть функция, которая возвращает запись в словаре на основе ключа (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.