2010-03-25 26 views
8

Ho bisogno di implementare Dizionario concorrente perché .Net non contiene un'implementazione concorrente per le collezioni (Poiché .NET4 sarà contenuto). Posso usarlo per la "Power Threading Library" di Jeffrey Richter o presentare varianti implementate o qualche consiglio da implementare? Grazie ...Concurrent Dictionary in C#

risposta

3

È possibile utilizzare Reflector per visualizzare il codice sorgente dell'implementazione simultanea di .NET 4.0 RC e copiarlo sul proprio codice. In questo modo avrai meno problemi durante la migrazione a .NET 4.0.

+1

A meno che non utilizzi nuove funzionalità che non sono disponibili in dotNET 3.5. E potrebbero esserci problemi di copyright qui. –

+0

Grazie, ci ho pensato. – jitm

+7

Vorrei scoraggiare l'ingegneria inversa del 4.0 Fx. Questo è un problema risolvibile/risolvibile per il quale esistono soluzioni note/testate. Puoi usare 4.0 Fx come ispirazione, ma per il resto non penso che questo sia un buon consiglio. –

3

Ho scritto un dizionario simultaneamente (prima dello spazio dei nomi di .NET 4.0 System.Collections.Concurrent); non c'è molto da fare In pratica, vuoi solo assicurarti che determinati metodi non vengano richiamati contemporaneamente, ad esempio Contains e Remove o qualcosa del genere.

Quello che ho fatto è stato quello di utilizzare una scrittura ReaderWriterLock (in .NET 3.5 e, soprattutto, si potrebbe andare con ReaderWriterLockSlim) e chiamare AcquireReaderLock per tutti "leggere" le operazioni (come this[TKey], ContainsKey, etc.) e AcquireWriterLock per tutti" "operazioni (come this[TKey] = value, Add, Remove, ecc.). Assicurati di chiudere le chiamate di questo tipo in un blocco try/finally, rilasciando il blocco nel numero finally.

È anche consigliabile modificare leggermente il comportamento di GetEnumerator: anziché eseguire l'enumerazione sulla raccolta esistente, crearne una copia e consentirne l'enumerazione. Altrimenti incontrerai potenziali punti morti.

4

Ho scritto un wrapper thread-safe per la normale classe Dictionary che utilizza Interlock per proteggere il dizionario interno. Interlocked è di gran lunga il meccanismo di bloccaggio più veloce disponibile e offre prestazioni molto migliori rispetto a ReaderWriterLockSlim, Monitor o a qualsiasi altra serratura disponibile.

Il codice è stato utilizzato per implementare una classe Cache per Fasterflect, che è una libreria per accelerare la riflessione. Come tale abbiamo provato una serie di approcci diversi per trovare la soluzione più rapida possibile. È interessante notare che le nuove raccolte simultanee in .NET 4 sono notevolmente più veloci della mia implementazione, sebbene entrambe siano piuttosto dure rispetto alle soluzioni che utilizzano un meccanismo di blocco delle prestazioni inferiore. L'implementazione per .NET 3.5 si trova all'interno di una regione condizionale nella metà inferiore del file.

+1

Ho dato un'occhiata alla home page di Fasterflect e ho visto il tuo esempio di classe Person con quel numero di istanze all'interno della classe. Non ti aprirebbe a problemi di concorrenza in quanto non vi è alcun blocco su di esso? Recentemente ho fatto alcune verifiche che gli operatori C# ++/- non sono atomici e non ho visto alcuna informazione che contraddica la mia comprensione. –

+1

La classe Person è solo una classe di esempio utilizzata per mostrare come utilizzare Fasterflect. Non è pensato per essere thread sicuro. Il codice di cui mi riferivo sopra è la classe Cache che si trova nel progetto principale di Fasterflect. Fare clic sul collegamento Cache sopra per accedere direttamente al browser sorgente su CodePlex. –

0

Ecco una semplice implementazione che utilizza bloccaggio sano di mente (anche se Interlocked sarebbe probabilmente più veloce): http://www.tech.windowsapplication1.com/content/the-synchronized-dictionarytkey-tvalue

In sostanza, basta creare un dizionario involucro/decoratore e sincronizzare l'accesso a qualsiasi lettura/scrittura azioni.

Quando si passa a .Net 4.0, è sufficiente sostituire tutti i sovraccarichi con chiamate delegate al ConcurrentDictionary sottostante.