У меня есть сценарий, в котором мне нужно сохранить подсчитанный объект для заданного ключа в ConcurrentDictionary
, если количество ссылок достигает 0
, я хочу удалить ключ. Это должно быть потокобезопасным, поэтому я планирую использовать ConcurrentDictionary
.Как достичь функции remove_if в .NET ConcurrentDictionary
Образец программы следующим образом. В параллельном словаре у меня есть ключ и значение, значение KeyValuePair, которое содержит мой пользовательский объект и счетчик ссылок.
ConcurrentDictionary<string, KeyValuePair<object, int>> ccd =
new ConcurrentDictionary<string, KeyValuePair<object, int>>();
// following code adds the key, if not exists with reference
// count for my custom object to 1
// if the key already exists it increments the reference count
var addOrUpdateValue = ccd.AddOrUpdate("mykey",
new KeyValuePair<object, int>(new object(), 1),
(k, pair) => new KeyValuePair<object, int>(pair.Key, pair.Value + 1));
Теперь я хочу способ, чтобы удалить ключ, когда счетчик ссылок достигает 0. Я думал, удалить метод на ConcurrentDictionary
который принимает ключ и предикат, удаляет ключ, если возвращение предикат «истинный». Пример.
ConcurrentDictionary.remove(TKey, Predicate<TValue>).
Там нет такого метода на ConcurrentDictionary
, вопрос заключается в том, чтобы сделать то же самое в потоке безопасно?.
Ваш «AddOrUpdate» ошибочен.[Хотя методы являются потокобезопасными, делегаты, которых вы передаете, не синхронизированы] (http://stackoverflow.com/questions/10486579/concurrentdictionary-pitfall-are-delegates-factories-from-getoradd-and-addorup), это означает два потока могли бы сделать пару. Value + 1' одновременно, и одно из них не было записано. Также не гарантируется, что делегат Update будет вызываться только один раз, но вы не изменяете какое-либо внешнее состояние в обновлении, чтобы вы были в безопасности там. –
Каков способ синхронизации AddOrUpdate?. – bmadhu
Для вашего случая использования, я не знаю. бросание «блокировки» внутри него не решит проблему, потому что вам нужно заблокировать вызов, прежде чем он когда-либо попадет в обновление lambada. –