example concurrentbag concurrent collection c# .net multithreading collections

c# - concurrentbag - Enlazar colecciones seguras en.NET



concurrentdictionary c# example (4)

.NET 4 proporciona un conjunto de colecciones seguras para subprocesos en System.Collections.Concurrent

¿Cuál es el estándar hoy en día cuando uno necesita una colección de hilos seguros (por ejemplo, Conjunto). ¿Lo sincronizo yo mismo o hay una colección intrínsecamente segura para subprocesos?


.NET 4.0 Framework presenta varias colecciones seguras para hilos en System.Collections.Concurrent Namespace :

ConcurrentBag<T>
Representa una colección de objetos desordenada y segura para subprocesos.

ConcurrentDictionary <TKey, TValue>
Representa una colección segura de subprocesos de pares clave-valor a los que se puede acceder mediante varios subprocesos al mismo tiempo.

ConcurrentQueue<T>
Representa una colección FIFO (Primero en entrar, primero en salir) segura para subprocesos.

ConcurrentStack<T>
Representa una colección de último acceso entrante (LIFO) seguro para subprocesos.

Otras colecciones en .NET Framework no son seguras para subprocesos de forma predeterminada y deben bloquearse para cada operación:

lock (mySet) { mySet.Add("Hello World"); }


Además de las clases muy útiles en System.Collections.Concurrent , se System.Collections.Concurrent una técnica estándar en escenarios de lectura mayoritariamente rara vez (o si hay, sin embargo, escrituras frecuentes, pero no simultáneas) que también es aplicable a .Net. Copy-on-write .

Tiene un par de propiedades que son deseables en programas altamente concurrentes:

  • las instancias de los objetos de colección son inmutables (es decir, seguras para subprocesos, se pueden enumerar de forma segura sin bloquear)
  • la modificación puede tomar todo el tiempo que quiera, el rendimiento y la concurrencia de las lecturas no se ven afectados
  • se puede implementar genéricamente para convertir cualquier estructura de datos que no sea segura para subprocesos en una que sea

Limitación: si hay escrituras simultáneas, las modificaciones pueden tener que volverse a intentar, de modo que cuanto más escrituras concurrentes obtengan, menos eficiente será. (Eso es concurrencia optimista en el trabajo)

Editar El comentario de Scott Chamberlain me recordó que hay otra limitación: si sus estructuras de datos son enormes y las modificaciones ocurren a menudo, una copia con escritura puede ser prohibitiva tanto en términos de consumo de memoria como del costo de copia de la CPU.


La mayoría de las colecciones de Pre .NET 4.0 en .Net no son seguras para subprocesos. Tendrá que trabajar un poco para manejar la sincronización: http://msdn.microsoft.com/en-us/library/573ths2x.aspx

Cita del artículo:

Las clases de colecciones pueden hacerse seguras a través de cualquiera de los siguientes métodos:

Cree un contenedor seguro para subprocesos utilizando el método Sincronizado y acceda a la colección exclusivamente a través de ese contenedor.

Si la clase no tiene un método Sincronizado, deriva de la clase e implementa un método Sincronizado utilizando la propiedad SyncRoot.

Utilice un mecanismo de bloqueo, como la instrucción de bloqueo en C # (SyncLock en Visual Basic), en la propiedad SyncRoot al acceder a la colección.

Sync Root Property
Declaración de bloqueo

Object thisLock = new Object(); ...... lock (thisLock) { // Critical code section }

En .net 4.0 introdujo el espacio de nombres System.Collections.Concurrent

Bloqueo de la colección
ConcurrentBag<T>
Cola concurrente
Diccionario concurrente
Particionador Ordable
Partitioner
Particionador T