Dizionario thread-safe mediante la classe ConcurrentDictionary

di Cristian Civera, in .NET Framework,

Nello script #267 si è introdotto il problema della concorrenza nelle collezioni e come nel .NET Framework 4.0 la classe ConcurrentQueue, e in modo del tutto simile la ConcurrentStack, permetta di lavorare su di essa in tutta sicurezza.

Anche il dizionario soffre del medesimo problema e fortunatamente è disponibile una classe generica ConcurrentDictionary che permette di aggiungere, recuperare o rimuovere coppie di chiave/valore al riparo dai problemi di concorrenza. L'utilizzo, per via della chiave, è un po' più complesso, perciò in questo script si mostra qualche esempio di utilizzo. Si parte innanzitutto con la definizione del dizionario e il suo popolamento.

ConcurrentDictionary<String, DateTime> logins = new ConcurrentDictionary<String, DateTime>();
bool r = logins.TryAdd("Ricciolo", DateTime.Now);

La funzione TryAdd tenta di inserire l'elemento, perché se già presente non viene sostituito e semplicemente si ottiene false dalla chiamata. Se invece si vuole essere sicuri di aggiungere o di aggiornare la chiave, occorre utilizzare il metodo AddOrUpdate.

DateTime v = DateTime.Now;
logins.AddOrUpdate("Ricciolo", v, (key, current) => v);

La funzione accetta rispettivamente il nome della chiave, il valore da aggiungere e la funzione (nell'esempio una lambda) che viene chiamata nel caso l'elemento esista già. Questa funzione, a sua volta, riceve la chiave e il valore attuale, così da permettere di decidere se mantenere il valore attuale o sovrascriverlo. Nell'esempio precedente si sovrascrive sempre l'elemento. Da notare inoltre che un overload del metodo AddOrUpdate accetta una funzione anche per il valore da aggiungere così da posticipare la creazione dell'oggetto e relative operazioni solo se effettivamente l'oggetto va aggiunto. Entrambe le funzioni ritornano poi l'effettivo valore aggiunto o aggiornato nel dizionario.

Basandosi sempre sullo stesso meccanismo, GetOrAdd permette di leggere o aggiungere un elemento, passando il valore o la funzione da chiamare nel caso l'elemento non ci sia.

DateTime v = logins.GetOrAdd("Ricciolo", key => DateTime.Now);

Non rimane altro che la rimozione, possibile tramite il metodo TryRemove, che restituisce in out il valore presente nel dizionario, dopo averlo rimosso.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi