2011-11-22 21 views
58

Ho ragione di pensare questo è l'uso corretto di un Dizionario ConcurrentConcurrent Dizionario Utilizzo a norme

private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>(); 

//Main thread at program startup 

for(int i = 0; i < 4; i++) 
{ 
    myDic.Add(i, 0); 
} 

//Seperate threads use this to update a value 

myDic[InputID] = newLongValue; 

Non ho serrature, ecc e sono solo l'aggiornamento del valore nel dizionario anche se più thread potrebbero essere cercando di Fai lo stesso.

+2

Dipende - ha 'newLongValue' dipende dal valore precedente di' myDic [InputID] '? –

+74

1UP per il nome della variabile "myDic"! –

+2

si dovrebbe evitare di accedere direttamente con la chiave 'myDic [InputID]' per condizioni di gara. Dovresti provare 'GetOrAdd' –

risposta

52

Dipende da cosa intendi per thread-safe.

Da MSDN - How to: Add and Remove Items from a ConcurrentDictionary:

ConcurrentDictionary<TKey, TValue> è progettato per gli scenari multithread. Non è necessario utilizzare blocchi nel codice per aggiungere o rimuovere elementi dalla raccolta. Tuttavia, è sempre possibile che un thread recuperi un valore e un altro thread aggiorni immediatamente la raccolta dando alla stessa chiave un nuovo valore.

Quindi, è possibile ottenere un incoerente vista del valore di un elemento nel dizionario.

+1

Questo è un punto interessante! Useresti ancora un lucchetto in quello scenario? – Jon

+0

@Jon - Dipende dalla tua applicazione e se è OK. Ma direi che se vuoi avere viste coerenti degli oggetti, dovresti avvolgere ogni lettura e aggiornamento di un oggetto in un lucchetto. – Oded

+4

Penso che questo non sia quello che dice il doc. L'incoerenza ha a che fare con ciò che la vista contiene, se la vista è solo il valore, allora è perfettamente coerente.Finché si ottiene il valore di una chiave, il valore della chiave nel dizionario potrebbe cambiare. Questo è incoerente come il valore DateTime.Now. –

2

Sì, hai ragione.

Questo e la possibilità di enumerare il dizionario su un thread mentre lo si cambia su un altro thread sono gli unici mezzi di esistenza per quella classe.

+7

Quello che dovrei aggiungere è che [qui] (http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx) è informazioni utili su come e quando usare ' ConcurrentDictionary'. –

1

Il modo migliore per scoprirlo è controllare la documentazione MSDN.

Per ConcurrentDictionary pagina è http://msdn.microsoft.com/en-us/library/dd287191.aspx

Nella sezione sicurezza filo, si afferma "Tutti i membri pubblici e protetti di ConcurrentDictionary (Of TKey, TValue) sono thread-safe e possono essere utilizzati contemporaneamente da più thread."

Quindi dal punto di vista della concorrenza siete a posto.

0

Dipende, nel mio caso io preferisco usare questo metodo.

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>); 

Vedi MSDN Library per dettagli di utilizzo metodo.

utilizzo Esempio:

results.AddOrUpdate(
    Id, 
    id => new DbResult() { 
    Id = id, 
    Value = row.Value, 
    Rank = 1 
    }, 
    (id, v) => 
    { 
    v.Rank++; 
    return v; 
    }); 
+1

FYI: "Quando fornisci un metodo factory value (ai metodi GetOrAdd e AddOrUpdate), può effettivamente essere eseguito e il suo risultato viene scartato successivamente (perché alcuni altri thread hanno vinto la gara)." Maggiori informazioni qui: https://arbel.net/2013/02/03/best-practices-for-using-concurrentdictionary/ – keremispirli

+0

Sì, hai ragione, come si nota nella sezione commenti "Se si chiama AddOrUpdate contemporaneamente su thread diversi, addValueFactory può essere chiamato più volte, ma la sua coppia chiave/valore potrebbe non essere aggiunta al dizionario per ogni chiamata. " Quindi devi essere sicuro di non generare più oggetti persistenti. – Onur

+0

E se è necessario aggiornare i contenuti, non cambiando completamente l'oggetto archiviato, ad esempio per modificare una proprietà di un oggetto aggiunto in precedenza, questo metodo è utile, altrimenti è necessario utilizzare i blocchi o altri metodi di sincronizzazione. – Onur

Problemi correlati