2012-01-04 9 views
7

Estaba buscando un método en ConcurrentDictionary que me permitiera eliminar una entrada por clave, si y solo si el valor es igual al que especifico, algo así como el equivalente de TryUpdate, pero para remociones.Método de eliminación concurrentemente concurrente de ConcurrentDictionary

El único método que hace esto parece ser el siguiente método:

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

Es la aplicación explícita de la interfaz ICollection, en otras palabras, tiene que emitir mi ConcurrentDictionary a un ICollection primero para que me puede llamar a Eliminar.

Quitar hace exactamente lo que quiero, y que reparto es nada del otro mundo tampoco, también se muestra el código fuente se llama al método privado TryRemovalInternal con bool matchValue = true, por lo que todo parece agradable y limpio.

Lo que me preocupa un poco, sin embargo, es el hecho de que no se documenta como el método Remove optimismo concurrente de ConcurrentDictionary, por lo http://msdn.microsoft.com/en-us/library/dd287153.aspx simplemente duplica la ICollection repetitivo, y la How to: Add and Remove Items from a ConcurrentDictionary no menciona que el método sea.

¿Alguien sabe si ese es el camino a seguir, o hay algún otro método que me falta?

+0

Parece correcto (dado que es el mismo método que las llamadas 'TryRemove', solo con' matchValue' establecido como falso y 'oldValue' predeterminado) –

+2

Aunque no es un documento oficial, puede ser útil: http: // blogs. msdn.com/b/pfxteam/archive/2011/04/02/10149222.aspx – alexm

+0

@alexm Esto es bastante tranquilizador: si lo conviertes en una respuesta, ¡lo aceptaré! MS realmente debería actualizar su documentación, si es cierto que últimamente han "visto a mucha gente pedir más soporte en ConcurrentDictionary" ... –

Respuesta

4

Aunque no es un documento oficial, this MSDN blog post puede ser útil. La esencia de ese artículo: enviar a ICollection y llamar a su método Remove, tal como se describe en la pregunta, es el camino a seguir.

He aquí un fragmento de la entrada en el blog anterior, que lo envuelve en un métodos TryRemove de extensión:

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

Si usted no necesita todas las campanas & silbidos de ConcurrentDictionary, sólo se puede declarar su tipo que un 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"); 
    } 
} 

Me parece útil en la situación en la que sólo se necesita agregar y quitar, pero todavía quiere una iteración de subprocesos.

+0

Si hay escenarios en los que utilizaría un ConcDic, pero no necesita sus métodos especializados, no me he encontrado con ellos. Pero si los hubiera, su sugerencia sin duda haría redundante ese molde. Otoh, estoy bastante seguro de que este es un "reparto en tiempo de compilación" de todos modos, por lo que no hay ninguna penalización en el rendimiento. Solo un código algo más feo. –

+0

En el escenario que desea agregar y eliminar objetos del diccionario al mismo tiempo que se está iterando. Siendo que ConcurrentDictionary proporciona una instantánea clave, no obtendrá una excepción. – greyalien007

Cuestiones relacionadas