Когда ConcurrentDictionary TryRemove вернет false


будет ли он возвращать false только в том случае, если словарь не содержит значения для данного ключа или он также возвращает false из-за условий гонки потоков, например, другой поток добавляет/обновляет что-то?

вопрос в коде:

ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1); 

Edit: Я думаю, что он только вернет false, если он не содержит значения для данного ключа, но хочет быть абсолютно уверенным.

3 66

3 ответа:

пока Митч право и ConcurrentDictionary не уязвимым для конкуренции, я думаю, что ответ на вопрос, который вы задаете, что да, если ключ присутствует, TryRemove будет работать и вернется true.

в коде, который вы опубликовали, нет никакого способа, что TryRemove вернутся false С cd локальная переменная не используется нигде. Но если какой-то код в другом месте дал ссылку на это ConcurrentDictionary объект и удаление ключей отдельный поток, то вполне возможно, что TryRemove может вернуться false, даже здесь ... но только потому, что ключ уже был удалены, а не потому, что какое-то другое действие выполняется над словарем и ключ как-то "застрял" там.

The ConcurrentDictionary не страдает от условий гонки. Вот почему вы его используете.

Возвращаемое Значение

true, если объект был удален успешно; в противном случае false.

еще один момент, чтобы сделать:

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

этот комментарий неверен и, возможно, страдает от того же неправильного представления о том, что значит "попробовать". Речь идет не о параллельной попытке добавить, а о том, было ли значение уже добавлено с помощью key 1.

рассмотрим стандартный Dictionary<TKey,TValue>. Эквивалентный код будет:

if (!d.Contains(1))
    d.Add(1, "one");

это требует двух операций. Нет никакого способа, чтобы дизайн такой API, чтобы быть ориентирован на многопотоковое исполнение, так как cd может иметь значение с ключом 1 добавить вызов Contains и Add, что затем приведет к Add метания.

в параллельных коллекциях есть API, которые логически связывают эти пары test-and-do в единственные атомарные операции за одним API.