Pregunta

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?

¿Fue útil?

Solución

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

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top