Domanda

I was looking for a method in ConcurrentDictionary that allows me to remove an entry by key, if and only if the value is equal to one that I specify, something like the equivalent of TryUpdate, but for removals.

The only method that does this seems to be this method:

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

It is the explicit implementation of the ICollection interface, in other words, I have to cast my ConcurrentDictionary to an ICollection first so that I can call Remove.

Remove does exactly what I want, and that cast is no big deal either, also the source code shows it calls the private method TryRemovalInternal with bool matchValue = true, so it all looks nice and clean.

What worries me a bit however is the fact that it is not documented as the optimistically concurrent Remove method of ConcurrentDictionary, so http://msdn.microsoft.com/en-us/library/dd287153.aspx just duplicates the ICollection boilerplate, and the How to: Add and Remove Items from a ConcurrentDictionary does not mention that method either.

Does anyone know if that's the way to go, or is there some other method that I'm missing?

È stato utile?

Soluzione

Though it is not an official document, this MSDN blog post can be helpful. The gist of that article: casting to ICollection and calling its Remove method, just as described in the question, is the way to go.

Here's a snippet from the above blog post, which wraps it into a TryRemove extension methods:

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));
}

Altri suggerimenti

If you don't need all the bells & whistles of ConcurrentDictionary, you can just declare your type as an 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");
    }
}

I find this useful in situation in which you only need to add and remove, but still want a thread-safe iteration.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top