web-dev-qa-db-fra.com

Collections thread-safe dans .NET

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?

65
ripper234

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");
}
98
dtb

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

18
kemiller2002

.NET 4 fournit un ensemble de collections thread-safe sous System.Collections.Concurrent

4
Kai Wang

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:

  • les instances d'objet de collection elles-mêmes sont immuables (c'est-à-dire thread-safe, peuvent être énumérées en toute sécurité sans verrouillage)
  • la modification peut prendre autant de temps qu'elle le souhaite, les performances et la simultanéité des lectures ne sont pas affectées
  • peut être implémenté de manière générique pour transformer toute structure de données qui n'est pas thread-safe en une structure qui est

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.

1
Eugene Beresovsky