Compartir a través de


Colecciones seguras para subprocesos

System.Collections.Concurrent introduce el espacio de nombres , que incluye varias clases de colección que son a la vez seguras para subprocesos y escalables. Varios subprocesos pueden agregar o quitar elementos de estas colecciones de forma segura y eficaz, sin necesidad de sincronización adicional en el código de usuario. Al escribir código nuevo, use las clases de colección concurrente para agregar múltiples subprocesos a la colección de forma simultánea. Si solo lees de una colección compartida, puedes usar las clases del espacio de nombres System.Collections.Generic.

System.Collections y System.Collections.Generic

Las clases de colección del System.Collections espacio de nombres incluyen ArrayList y Hashtable. Estas clases proporcionan cierta seguridad para subprocesos a través de la propiedad Synchronized, que devuelve una envoltura segura para subprocesos sobre la colección. El envoltorio funciona bloqueando toda la colección en cada operación de adición o eliminación. Por consiguiente, cada subproceso que intenta acceder a la colección debe esperar su turno para tomar el único bloqueo. Este proceso no es escalable y puede provocar una degradación significativa del rendimiento de las colecciones grandes. Asimismo, el diseño no está protegido de las condiciones de carrera. Para obtener más información, vea Sincronización en colecciones genéricas.

Las clases de colección del System.Collections.Generic espacio de nombres incluyen List<T> y Dictionary<TKey,TValue>. Estas clases proporcionan una seguridad de tipos y un rendimiento mejorados comparados con las clases de System.Collections. Sin embargo, las System.Collections.Generic clases no proporcionan ninguna sincronización de subprocesos; el código de usuario debe proporcionar toda la sincronización cuando se agregan o quitan elementos en varios subprocesos simultáneamente.

Recomendamos usar las clases de colecciones concurrentes en el System.Collections.Concurrent espacio de nombres porque ofrecen seguridad de tipos y una seguridad de subprocesos más completa y eficaz.

Mecanismos de bloqueo específico y sin bloqueos

Algunos de los tipos de colección simultáneos usan mecanismos de sincronización ligeros, como SpinLock, SpinWait, SemaphoreSlimy CountdownEvent. Estos tipos de sincronización usan normalmente el giro activo durante breves períodos antes de colocar el subproceso en un verdadero estado de Wait. Cuando se prevé que los tiempos de espera sean breves, el giro es técnicamente menos costoso que la espera, que implica una costosa transición del kernel. Para las clases de colección que utilizan el giro, esta eficacia significa que se pueden agregar y quitar varios subprocesos a velocidad rápida. Para obtener más información sobre la comparación del giro y el bloqueo, consulte SpinLock y SpinWait.

Las clases ConcurrentQueue<T> y ConcurrentStack<T> no usan bloqueos en absoluto. En su lugar, dependen de las operaciones Interlocked para lograr la seguridad para subprocesos.

Nota:

Dado que las clases de colecciones simultáneas admiten ICollection, proporcionan implementaciones para las IsSynchronized propiedades y SyncRoot , aunque estas propiedades son irrelevantes. IsSynchronized siempre devuelve false y, SyncRoot siempre null es (Nothing en Visual Basic).

En la siguiente tabla se enumeran los tipos de colección del espacio de nombres System.Collections.Concurrent:

Tipo Descripción
BlockingCollection<T> Proporciona funcionalidad de límite y bloqueo para cualquier tipo que implemente IProducerConsumerCollection<T>. Para obtener más información, consulte Información general sobre BlockingCollection.
ConcurrentDictionary<TKey,TValue> Implementación segura para subprocesos de un diccionario de pares clave-valor.
ConcurrentQueue<T> Implementación segura para subprocesos de una cola FIFO (primero en entrar, primero en salir).
ConcurrentStack<T> Implementación segura para subprocesos de una pila LIFO (último en entrar, primero en salir).
ConcurrentBag<T> Implementación segura para subprocesos de una colección no ordenada de elementos.
IProducerConsumerCollection<T> La interfaz que un tipo debe implementar para poder ser utilizado en un BlockingCollection.
Título Descripción
Información general sobre BlockingCollection Describe la funcionalidad proporcionada por el BlockingCollection<T> tipo.
Cómo: Agregar y quitar elementos de un ConcurrentDictionary Describe cómo agregar y quitar elementos de un ConcurrentDictionary<TKey,TValue>
Procedimiento: Agregar y tomar elementos de forma individual en una clase BlockingCollection Describe cómo agregar y recuperar elementos de una colección de bloqueo sin usar el enumerador de solo lectura.
Cómo: Agregar funcionalidad de límite y bloqueo a una colección Describe cómo usar cualquier clase de colección como mecanismo de almacenamiento subyacente para una IProducerConsumerCollection<T> colección.
Procedimiento: Utilizar ForEach para quitar elementos de BlockingCollection Describe cómo usar foreach (For Each en Visual Basic) para quitar todos los elementos de una colección de bloqueo.
Procedimiento: Usar matrices de colecciones de bloqueo en una canalización Describe cómo usar varias colecciones de bloqueo al mismo tiempo para implementar una canalización.
Cómo: Crear un grupo de objetos mediante concurrentBag Muestra cómo usar un contenedor simultáneo para mejorar el rendimiento en escenarios en los que puede reutilizar objetos en lugar de crear nuevos de forma continua.

Referencia