Оптимистически параллельный метод Remove ConcurrentDictionary - PullRequest
7 голосов
/ 04 января 2012

Я искал метод в ConcurrentDictionary, который позволил бы мне удалить запись по ключу, если и только если значение равно указанному мной, что-то вроде эквивалента TryUpdate , но дляremoveals.

Единственный метод, который делает это, кажется, этот метод:

ICollection<KeyValuePair<K, V>>.Remove(KeyValuePair<K, V> keyValuePair)

Это явная реализация интерфейса ICollection, другими словами, я должен привести свой ConcurrentDictionary ксначала ICollection, чтобы я мог вызвать Remove.

Remove выполняет именно то, что я хочу, и это приведение также не представляет особой проблемы, также исходный код показывает, что он вызывает закрытый метод TryRemovalInternal с bool matchValue =true , так что все выглядит красиво и чисто.

Однако меня немного беспокоит тот факт, что он не задокументирован как оптимистически параллельный метод Remove ConcurrentDictionary, поэтому http://msdn.microsoft.com/en-us/library/dd287153.aspx простодублирует шаблон ICollection и Как: добавлять и удалять элементы из ConcurrentDictionary также не упоминает этот метод.

Кто-нибудь знает, так ли это, или есть какой-то другой метод, который мне не хватает?

Ответы [ 2 ]

4 голосов
/ 04 января 2012

Хотя это не официальный документ, этот пост в MSDN может быть полезен. Суть этой статьи: приведение к ICollection и вызов его метода Remove, как описано в вопросе, - это путь.

Вот фрагмент из вышеприведенного сообщения в блоге, в котором он включает TryRemove методы расширения:

public static bool TryRemove<TKey, TValue>(
    this ConcurrentDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
    if (dictionary == null)
      throw new ArgumentNullException("dictionary");
    return ((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Remove(
        new KeyValuePair<TKey, TValue>(key, value));
}
0 голосов
/ 30 ноября 2013

Если вам не нужны все функции ConcurrentDictionary, вы можете просто объявить свой тип как IDictionary.

public class ClassThatNeedsDictionary
{
    private readonly IDictionary<string, string> storage;

    public ClassThatNeedsDictionary()
    {
        storage = new ConcurrentDictionary<string, string>();
    }

    public void TheMethod()
    {
        //still thread-safe
        this.storage.Add("key", "value");
        this.storage.Remove("key");
    }
}

Я нахожу это полезным в ситуации, когда вам нужно только добавлять и удалять, но все же требуется итерация, безопасная для потоков.

...