У меня есть ConcurrentDictionary, который отображает простой тип в списке:Безопасное удаление отображение списка из ConcurrentDictionary
var dict = new ConcurrentDictionary<string, List<string>>();
я могу использовать AddOrUpdate() для удовлетворения как инициализации списка при добавлении первого значения и добавления последующих значений в список.
Однако это не относится к удалению. Если я что-то вроде:
public void Remove(string key, string value)
{
List<string> list;
var found = dict.TryGetValue(key, out list);
if (found)
{
list.Remove(value);
if (list.Count == 0)
{
// warning: possible race condition here
dict.TryRemove(key, out list);
}
}
}
... где мое намерение состоит в том, чтобы не удалить ключ полностью, если соответствующий список больше не имеет значение (аналогичного подсчет ссылок, в концепции), то я рискуя состоянием гонки, потому что кто-то мог добавить что-то в список сразу после того, как я проверил, пусто ли он.
Хотя я использую список в этом простом примере, у меня обычно есть ConcurrentBag или ConcurrentDictionary в таких сценариях, и риск очень похож.
Есть ли способ безопасного удаления ключа, когда соответствующая коллекция пуста, не прибегая к замкам?
Is. есть также потенциальная гонка между вызовом 'TryGetValue' и' Remove'? – doctorlove
Я мог ошибаться, но я так не думаю ... если кто-то добавит что-то перед проверкой пустоты, тогда он не будет пустым .. – Gigi
Что делать, если они вызывают удаление? – doctorlove