Colecciones seguras para subprocesosThread-Safe Collections

.NET Framework 4 introduce el espacio de nombres System.Collections.Concurrent, que incluye varias clases de colección que son a la vez seguras para subprocesos y escalables.The .NET Framework 4 introduces the System.Collections.Concurrent namespace, which includes several collection classes that are both thread-safe and scalable. Varios subprocesos pueden agregar o quitar elementos de estas colecciones sin ningún riesgo y de un modo eficaz, sin requerir una sincronización adicional en código de usuario.Multiple threads can safely and efficiently add or remove items from these collections, without requiring additional synchronization in user code. Al escribir un código nuevo, utilice las clases de colección simultáneas siempre que varios subprocesos se vayan a escribir en la colección de forma simultánea.When you write new code, use the concurrent collection classes whenever multiple threads will write to the collection concurrently. Si solo está leyendo en una colección compartida, puede utilizar las clases en el espacio de nombres System.Collections.Generic.If you are only reading from a shared collection, then you can use the classes in the System.Collections.Generic namespace. Recomendamos no utilizar clases de colección 1.0 a menos que estén destinadas a .NET Framework 1.1. o un runtime de una versión anterior.We recommend that you do not use 1.0 collection classes unless you are required to target the .NET Framework 1.1 or earlier runtime.

Sincronización de subprocesos en las colecciones de .NET Framework 1.0 y 2.0Thread Synchronization in the .NET Framework 1.0 and 2.0 Collections

Las colecciones introducidas en .NET Framework 1.0 se encuentran en el espacio de nombres System.Collections.The collections introduced in the .NET Framework 1.0 are found in the System.Collections namespace. Estas colecciones, que incluyen ArrayList y Hashtable utilizados habitualmente, proporcionan cierta seguridad para subprocesos mediante la propiedad Synchronized, que devuelve un contenedor seguro para subprocesos en torno a la colección.These collections, which include the commonly used ArrayList and Hashtable, provide some thread-safety through the Synchronized property, which returns a thread-safe wrapper around the collection. El contenedor funciona bloqueando toda la colección en cada operación de agregar o quitar.The wrapper works by locking the entire collection on every add or remove operation. Por consiguiente, cada subproceso que intenta tener acceso a la colección debe esperar su turno para tomar el único bloqueo.Therefore, each thread that is attempting to access the collection must wait for its turn to take the one lock. Esto no es escalable y puede producir una degradación significativa del rendimiento en las colecciones grandes.This is not scalable and can cause significant performance degradation for large collections. Asimismo, el diseño no está totalmente protegido de las condiciones de carrera.Also, the design is not completely protected from race conditions. Para obtener más información, vea Synchronization in Generic Collections (Sincronización de colecciones genéricas).For more information, see Synchronization in Generic Collections.

Las clases de colección introducidas en .NET Framework 2.0 se encuentran en el espacio de nombres System.Collections.Generic.The collection classes introduced in the .NET Framework 2.0 are found in the System.Collections.Generic namespace. Éstas incluyen List<T>, Dictionary<TKey,TValue>, etc.These include List<T>, Dictionary<TKey,TValue>, and so on. Estas clases proporcionan una seguridad de tipos y un rendimiento mejorados comparados con las clases de .NET Framework 1.0.These classes provide improved type safety and performance compared to the .NET Framework 1.0 classes. Sin embargo, las clases de colección de .NET Framework 2.0 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.However, the .NET Framework 2.0 collection classes do not provide any thread synchronization; user code must provide all synchronization when items are added or removed on multiple threads concurrently.

Se recomiendan las clases de colección simultáneas en .NET Framework 4 porque proporcionan no solo la seguridad de tipos de las clases de colección de .NET Framework 2.0, sino también una seguridad de subprocesos más eficaz y completa que las colecciones de .NET Framework 1.0.We recommend the concurrent collections classes in the .NET Framework 4 because they provide not only the type safety of the .NET Framework 2.0 collection classes, but also more efficient and more complete thread safety than the .NET Framework 1.0 collections provide.

Mecanismos de bloqueo específico y sin bloqueosFine-Grained Locking and Lock-Free Mechanisms

Algunos de los tipos de colección simultáneos utilizan mecanismos de sincronización ligeros como SpinLock, SpinWait, SemaphoreSlim y CountdownEvent, que son nuevos en .NET Framework 4.Some of the concurrent collection types use lightweight synchronization mechanisms such as SpinLock, SpinWait, SemaphoreSlim, and CountdownEvent, which are new in the .NET Framework 4. Estos tipos de sincronización utilizan normalmente giro de ocupado durante breves períodos antes de colocar el subproceso en un verdadero estado de espera.These synchronization types typically use busy spinning for brief periods before they put the thread into a true Wait state. Cuando se prevé que los tiempos de espera sean muy cortos, el giro es técnicamente menos costoso que la espera, que implica una costosa transición del kernel.When wait times are expected to be very short, spinning is far less computationally expensive than waiting, which involves an expensive kernel transition. Para las clases de colección que utilizan el giro, esta eficacia significa que se pueden agregar y quitar varios subprocesos con una tasa muy alta.For collection classes that use spinning, this efficiency means that multiple threads can add and remove items at a very high rate. Para más información sobre la comparación del giro y el bloque, consulte SpinLock y SpinWait.For more information about spinning vs. blocking, see SpinLock and SpinWait.

Las clases ConcurrentQueue<T> y ConcurrentStack<T> no utilizan bloqueos en absoluto.The ConcurrentQueue<T> and ConcurrentStack<T> classes do not use locks at all. En su lugar, dependen de las operaciones Interlocked para lograr la seguridad para subprocesos.Instead, they rely on Interlocked operations to achieve thread-safety.

Nota

Como las clases de colección simultáneas son compatibles con ICollection, proporcionan implementaciones para las propiedades IsSynchronized y SyncRoot, aunque estas propiedades sean irrelevantes.Because the concurrent collections classes support ICollection, they provide implementations for the IsSynchronized and SyncRoot properties, even though these properties are irrelevant. IsSynchronized devuelve siempre false y SyncRoot es siempre null (Nothing en Visual Basic).IsSynchronized always returns false and SyncRoot is always null (Nothing in Visual Basic).

La siguiente tabla enumera los tipos de colección en el espacio de nombres System.Collections.Concurrent.The following table lists the collection types in the System.Collections.Concurrent namespace.

TipoType DESCRIPCIÓNDescription
BlockingCollection<T> Proporciona funcionalidad de límite y bloqueo para cualquier tipo que implemente IProducerConsumerCollection<T>.Provides bounding and blocking functionality for any type that implements IProducerConsumerCollection<T>. Para obtener más información, consulte Información general sobre BlockingCollection.For more information, see BlockingCollection Overview.
ConcurrentDictionary<TKey,TValue> Implementación segura para subprocesos de un diccionario de pares clave-valor.Thread-safe implementation of a dictionary of key-value pairs.
ConcurrentQueue<T> Implementación segura para subprocesos de una cola FIFO (primero en entrar, primero en salir).Thread-safe implementation of a FIFO (first-in, first-out) queue.
ConcurrentStack<T> Implementación segura para subprocesos de una pila LIFO (último en entrar, primero en salir).Thread-safe implementation of a LIFO (last-in, first-out) stack.
ConcurrentBag<T> Implementación segura para subprocesos de una colección no ordenada de elementos.Thread-safe implementation of an unordered collection of elements.
IProducerConsumerCollection<T> Interfaz que debe implementar un tipo para su uso en BlockingCollection.The interface that a type must implement to be used in a BlockingCollection.
TitleTitle DESCRIPCIÓNDescription
Información general sobre BlockingCollectionBlockingCollection Overview Describe la funcionalidad proporcionada por el tipo BlockingCollection<T>.Describes the functionality provided by the BlockingCollection<T> type.
Cómo: agregar y quitar elementos de ConcurrentDictionaryHow to: Add and Remove Items from a ConcurrentDictionary Describe cómo agregar y quitar los elementos de ConcurrentDictionary<TKey,TValue>Describes how to add and remove elements from a ConcurrentDictionary<TKey,TValue>
Cómo: agregar y tomar elementos de forma individual en una clase BlockingCollectionHow to: Add and Take Items Individually from a BlockingCollection Describe cómo agregar y recuperar elementos de una colección de bloqueo sin utilizar el enumerador de solo lectura.Describes how to add and retrieve items from a blocking collection without using the read-only enumerator.
Cómo: agregar la funcionalidad de límite y bloqueo a una colecciónHow to: Add Bounding and Blocking Functionality to a Collection Describe cómo utilizar cualquier clase de colección como mecanismo de almacenamiento subyacente para una colección IProducerConsumerCollection<T>.Describes how to use any collection class as the underlying storage mechanism for an IProducerConsumerCollection<T> collection.
Cómo: utilizar ForEach para quitar elementos de BlockingCollectionHow to: Use ForEach to Remove Items in a BlockingCollection Describe cómo utilizar foreach, (For Each en Visual Basic) para quitar todos los elementos en una colección de bloqueo.Describes how to use foreach, (For Each in Visual Basic) to remove all items in a blocking collection.
Cómo: usar matrices de colecciones de bloqueo en una canalizaciónHow to: Use Arrays of Blocking Collections in a Pipeline Describe cómo utilizar varias colecciones de bloqueo para implementar una canalización al mismo tiempo.Describes how to use multiple blocking collections at the same time to implement a pipeline.
Cómo: crear un grupo de objetos usando ConcurrentBagHow to: Create an Object Pool by Using a ConcurrentBag Muestra cómo usar un controlador simultáneo para mejorar el rendimiento en escenarios donde puede reutilizar objetos en lugar de crear continuamente otros nuevos.Shows how to use a concurrent bag to improve performance in scenarios where you can reuse objects instead of continually creating new ones.

ReferenciaReference

System.Collections.Concurrent