Quelle est la norme de nos jours quand on a besoin d'une collection thread-safe (par exemple Set). Dois-je le synchroniser moi-même ou existe-t-il une collection intrinsèquement sécurisée pour les threads?
Le .NET 4.0 Framework introduit plusieurs collections thread-safe dans System.Collections.Concurrent Namespace :
ConcurrentBag <T>
Représente une collection d'objets non-thread-safe.ConcurrentDictionary <TKey, TValue>
Représente une collection thread-safe de paires clé-valeur accessibles simultanément par plusieurs threads.ConcurrentQueue <T>
Représente une collection FIFO (thread-first first-in-out).ConcurrentStack <T>
Représente une collection LIFO (thread-safe last-in-first out).
Les autres collections du .NET Framework ne sont pas thread-safe par défaut et doivent être verrouillées pour chaque opération:
lock (mySet)
{
mySet.Add("Hello World");
}
Avant .net 4.0, la plupart des collections en .Net ne sont pas thread-safe. Vous devrez travailler vous-même pour gérer la synchronisation: http://msdn.Microsoft.com/en-us/library/573ths2x.aspx
Citation de l'article:
Les classes de collections peuvent être sécurisées pour les threads en utilisant l'une des méthodes suivantes:
Créez un wrapper thread-safe à l'aide de la méthode synchronisée et accédez à la collection exclusivement via ce wrapper.
Si la classe n'a pas de méthode synchronisée, dérivez de la classe et implémentez une méthode synchronisée à l'aide de la propriété SyncRoot.
Utilisez un mécanisme de verrouillage, tel que l'instruction de verrouillage en C # (SyncLock dans Visual Basic), sur la propriété SyncRoot lors de l'accès à la collection.
Sync Root Property
Déclaration de verrouillage
Object thisLock = new Object();
......
lock (thisLock)
{
// Critical code section
}
Dans .net 4.0 le introduit l'espace de noms System.Collections.Concurrent
Collection de blocage
Sac simultané
File d'attente simultanée
Dictionnaire simultané
Partitionneur Ordable
Partitionneur
Partitionneur T
.NET 4 fournit un ensemble de collections thread-safe sous System.Collections.Concurrent
En plus des classes très utiles de System.Collections.Concurrent
, une technique standard dans les scénarios de lecture la plupart du temps rarement modifiée (ou s'il existe des écritures fréquentes mais non simultanées) qui s'applique également à .Net est appelée Copie sur écriture .
Il possède quelques propriétés souhaitables dans les programmes hautement concurrents:
Limitation: s'il y a des écritures simultanées, des modifications devront peut-être être réessayées, de sorte que plus les écritures simultanées sont nombreuses, moins elles deviennent efficaces. (C'est concurrence optimiste au travail)
Modifier Le commentaire de Scott Chamberlain m'a rappelé qu'il y a une autre limitation: si vos structures de données sont énormes et que des modifications se produisent souvent, une copie tout-sur-écriture peut être prohibitif à la fois en termes de consommation de mémoire et le coût CPU de copie impliqués.