2012-01-04 12 views
7

Cercavo un metodo in ConcurrentDictionary che mi consenta di rimuovere una voce per chiave, se e solo se il valore è uguale a uno specificato, qualcosa come l'equivalente di TryUpdate, ma per traslochi.ConcurrentDictionary in modo ottimistico simultaneo Metodo di rimozione

L'unico metodo che fa questo sembra essere questo metodo:

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

E 'l'implementazione esplicita dell'interfaccia ICollection, in altre parole, devo lanciare la mia ConcurrentDictionary a un ICollection prima in modo che io puoi chiamare Rimuovi.

Rimuovere fa esattamente quello che voglio, e che cast è un grosso problema sia, anche il codice sorgente mostra richiama il metodo privato TryRemovalInternal con bool matchValue = true, quindi sembra tutto bello e pulito.

Quello che mi preoccupa un po 'è però il fatto che non è documentato come il metodo Remove ottimismo concomitante di ConcurrentDictionary, quindi http://msdn.microsoft.com/en-us/library/dd287153.aspx basta duplica il boilerplate ICollection, e il How to: Add and Remove Items from a ConcurrentDictionary non dice che il metodo sia.

Qualcuno sa se questa è la strada da percorrere, o c'è qualche altro metodo che mi manca?

+0

Sembra giusto (poiché è lo stesso metodo che chiama "TryRemove' chiama, solo con' matchValue' imposta false e 'oldValue' è predefinito) –

+2

Anche se non è un documento ufficiale, può essere utile: http: // blog. msdn.com/b/pfxteam/archive/2011/04/02/10149222.aspx – alexm

+0

@alexm Questo è abbastanza rassicurante - Se lo trasformi in una risposta, lo accetto! MS dovrebbe davvero aggiornare la propria documentazione, se è vero che ultimamente hanno "visto diverse persone chiedere ulteriore supporto su ConcurrentDictionary" ... –

risposta

4

Anche se non è un documento ufficiale, this MSDN blog post può essere utile. Il succo di quell'articolo: il casting su ICollection e il suo metodo Remove, come descritto nella domanda, è la strada da seguire.

Ecco un frammento dal post di cui sopra, che avvolge in una modalità TryRemove estensione:

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

Se non avete bisogno di tutte le campane & fischietti di ConcurrentDictionary, si può semplicemente dichiarare il vostro tipo 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"); 
    } 
} 

ho trovato utile in situazioni in cui è necessario solo aggiungere e rimuovere, ma vuole ancora un iterazione thread-safe.

+0

Se ci sono degli scenari in cui si dovrebbe usare un ConcDic, ma non sono necessari i suoi metodi specializzati, io non li ho mai incontrati Ma se ci fosse, il tuo suggerimento sicuramente renderebbe ridondante quel cast. Otoh, sono abbastanza sicuro che si tratti comunque di un cast "compile-time", quindi nessuna penalizzazione delle prestazioni. Solo un po 'più brutto codice. –

+0

Nello scenario in cui si desidera aggiungere e rimuovere oggetti dal dizionario nello stesso momento in cui viene iterato. Essendo che ConcurrentDictionary fornisce un'istantanea chiave, non otterrai un'eccezione. – greyalien007

Problemi correlati