2010-01-11 12 views
19

Se inizializzo un dizionario generico una volta e non sono consentiti ulteriori aggiunte/aggiornamenti/rimuovi, è sicuro che più thread leggano da esso senza alcun blocco (assumendo che il dizionario è inizializzato prima dell'avvio dei lettori)?Sicurezza thread di un dizionario <TKey, TValue>

C'è una nota nella guida per la HashTable non generico che dice che è sicuro per più lettori, ma non ho visto un simile non per il Dizionario generico

risposta

34

Per riferimento futuro, la documentazione è qui:

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

Dice:

Un Dizionario può supportare più lettori contemporaneamente, purché la collezione non venga modificata. Anche così, enumerare tramite una raccolta è intrinsecamente non una procedura thread-safe . Nel raro caso in cui un'enumerazione contenga gli accessi in scrittura , la raccolta deve essere bloccata durante l'intera enumerazione . Per consentire l'accesso alla raccolta da più thread per la lettura e la scrittura , è necessario implementare la propria sincronizzazione .

+0

Just voglio assicurarmi di capire che "Anche così ..." parte del paragrafo citato correttamente. È vero che: (1) se il dizionario non sarà più modificato (come menzionato nella domanda dell'OP), anche l'enumerazione non sarà un problema. (2) se il dizionario sarà potenzialmente modificato in futuro, anche l'enumerazione 'ConcurrentDictionary' è" intrinsecamente non una procedura thread-safe ". Corretta? – RayLuo

+0

@RayLuo: in generale non è consentito modificare una raccolta mentre un'enumerazione è "in volo" indipendentemente dal fatto che sia multithread o single threaded. –

+0

Le raccolte di framework simultanee (ad es. 'System.Collections.Concurrent.ConcurrentDictionary') generalmente consentono modifiche durante l'enumerazione. Tuttavia, lo fanno facendo una copia della collezione e facendoti elencare la copia. E l'intera raccolta è bloccata mentre viene eseguita la copia. Un ingegnere del framework potrebbe obiettare che questo significa che non stai modificando la raccolta mentre l'enumerazione è "in volo" (poiché sotto il cofano, l'intera cosa era bloccata mentre l'enumerazione era "in volo"), ma dalla prospettiva di un utente quadro , l'elenco è in volo. – Brian

13

Sì, è sicuro se don modificare il dizionario più. sicurezza dei thread è solo un problema in scenari di lettura/scrittura

+11

Tuttavia, è necessario tenere conto dello stato interno. Esternamente, puoi leggere solo un valore dal dizionario. Tuttavia, tuttavia, non si conoscono le transizioni di stato che possono verificarsi durante il recupero. – JMarsch

+0

OP @JMarsch ha commentato sopra e ha ricevuto 10 voti positivi. In che modo questa cosa dello "stato interno" influenzerebbe lo scenario dell'OP? Va ancora bene se 'Se inizializzo un dizionario generico una volta, e non sono permessi ulteriori aggiunte/aggiornamenti/rimossi, è sicuro che ci siano più thread che ne leggono senza blocco (supponendo che il dizionario sia inizializzato prima dell'avvio dei lettori)? – RayLuo

+0

Per un dizionario, sì, la risposta di Eric Lippert è valida. La cosa importante da ricordare dal mio commento è che, in generale, non è sufficiente presumere che una struttura di dati sia infallibile se si legge solo su di essa, perché non si sa come la lettura influenzi lo stato interno. Nel caso del dizionario, risulta che le operazioni di lettura sono davvero sicure fintanto che nessuno lo scrive mai mentre i lettori concorrenti lo utilizzano. Quindi nel tuo esempio, dove l'hai inizializzato una volta e poi ne hai letto solo, sei al sicuro. – JMarsch

Problemi correlati