Когда 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 ответа:
пока Митч право и
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.