Estructuras de datos para la programación paralela

.NET Framework versión 4 incorpora varios tipos nuevos que resultan útiles para la programación en paralelo, entre los que se incluye un conjunto de clases de colección simultáneas, primitivas de sincronización ligeras y tipos de inicialización diferida. Puede usar estos tipos con cualquier código de aplicación multiproceso, incluso con la biblioteca TPL (Task Parallel Library, biblioteca de procesamiento paralelo basado en tareas) y PLINQ.

Clases de colección simultáneas

Las clases de colección del espacio de nombres System.Collections.Concurrent proporcionan operaciones Add y Remove seguras para subprocesos que evitan los bloqueos en la medida de lo posible y, cuando es necesario, usan bloqueos específicos. A diferencia de las colecciones que se incorporaron en las versiones 1.0 y 2.0 de .NET Framework, una clase de colección simultánea no requiere que el código de usuario tome ningún bloqueo cuando obtiene acceso a los elementos. Las clases de colección simultáneas pueden mejorar significativamente el rendimiento frente a tipos como System.Collections.ArrayList y System.Collections.Generic.List<T> (con bloqueo implementado por el usuario) en escenarios en lo que varios subprocesos agregan y quitan elementos de una colección.

En la tabla siguiente se muestran las nuevas clases de colección simultáneas:

Tipo

Descripción

System.Collections.Concurrent.BlockingCollection<T>

Proporciona capacidades de bloqueo y establecimiento de límites en colecciones seguras para subprocesos que implementan System.Collections.Concurrent.IProducerConsumerCollection<T>. Los subprocesos de productor se bloquean si no hay ranuras disponibles o si la colección está completa. Los subprocesos de consumidor se bloquean si la colección está vacía. Este tipo también permite el acceso sin bloqueo de los subprocesos de consumidor y productor. BlockingCollection<T> puede usarse como clase base o dispositivo de copia de seguridad para proporcionar el bloqueo y el establecimiento de límites de cualquier clase de colección que admita IEnumerable<T>.

System.Collections.Concurrent.ConcurrentBag<T>

Implementación de un contenedor seguro para subprocesos que proporciona operaciones Add y Get escalables.

System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>

Tipo de diccionario simultáneo y escalable.

System.Collections.Concurrent.ConcurrentQueue<T>

Cola FIFO simultánea y escalable.

System.Collections.Concurrent.ConcurrentStack<T>

Pila LIFO simultánea y escalable.

Para obtener más información, vea Colecciones seguras para subprocesos.

Primitivas de sincronización

Las nuevas primitivas de sincronización del espacio de nombres System.Threading proporcionan una simultaneidad específica y un mayor rendimiento ya que evitan los costosos mecanismos de bloqueo que se encuentran en el código multithreading heredado. Algunos de los nuevos tipos, como System.Threading.Barrier y System.Threading.CountdownEvent, no tienen equivalente en versiones anteriores de .NET Framework.

En la tabla siguiente, se muestran los nuevos tipos de sincronización:

Tipo

Descripción

System.Threading.Barrier

Permite que varios subprocesos trabajen en un algoritmo en paralelo proporcionando un punto en el que cada tarea puede señalar su llegada y bloquearse hasta que algunas o todas las tareas hayan llegado. Para obtener más información, vea Barrier (.NET Framework).

System.Threading.CountdownEvent

Simplifica los escenarios de bifurcación y unión proporcionando un mecanismo de encuentro sencillo. Para obtener más información, vea CountdownEvent.

System.Threading.ManualResetEventSlim

Primitiva de sincronización similar a System.Threading.ManualResetEvent. ManualResetEventSlim es un objeto ligero, pero solo puede usarse en la comunicación que tiene lugar dentro de un proceso. Para obtener más información, vea ManualResetEvent y ManualResetEventSlim.

System.Threading.SemaphoreSlim

Primitiva de sincronización que limita el número de subprocesos que pueden obtener acceso a la vez a un recurso o grupo de recursos. Para obtener más información, vea Semaphore y SemaphoreSlim.

System.Threading.SpinLock

Primitiva de bloqueo de exclusión mutua que hace que el subproceso que está intentando adquirir el bloqueo espere en un bucle o ciclo durante un período de tiempo antes de que se produzca su cuanto. En escenarios en los que se prevé que la espera del bloqueo será breve, SpinLock proporciona mayor rendimiento que otras formas de bloqueo. Para obtener más información, vea SpinLock.

System.Threading.SpinWait

Tipo pequeño y ligero que iterará en ciclos durante un período especificado y situará el subproceso en estado de espera si el recuento de ciclos se supera. Para obtener más información, vea SpinWait.

Para obtener más información, vea:

Clases de inicialización diferida

Con la inicialización diferida, la memoria de un objeto no se asigna hasta que es necesario. La inicialización diferida puede mejorar el rendimiento al extender las asignaciones de objetos uniformemente a lo largo de la duración de un programa. Puede habilitar la inicialización diferida en cualquier tipo personalizado encapsulando el tipo Lazy<T>.

En la tabla siguiente, se muestran los tipos de inicialización diferida:

Tipo

Descripción

System.Lazy<T>

Proporciona una inicialización diferida ligera y segura para subprocesos.

System.Threading.ThreadLocal<T>

Proporciona un valor de inicialización diferida por cada subproceso, donde cada subproceso invoca de forma diferida la función de inicialización.

System.Threading.LazyInitializer

Proporciona métodos estáticos que evitan tener que asignar una instancia de inicialización diferida dedicada. En su lugar, usan referencias para garantizar que los destinos se han inicializado a medida que se va obteniendo acceso a ellos.

Para obtener más información, vea Inicialización diferida.

Excepciones agregadas

El tipo System.AggregateException se puede utilizar para capturar varias excepciones que se producen simultáneamente en diferentes subprocesos y devolverlas al subproceso de unión como una sola excepción. Los tipos System.Threading.Tasks.Task y System.Threading.Tasks.Parallel así como la PLINQ usan AggregateException en gran medida con este propósito. Para obtener más información, vea Cómo: Controlar excepciones iniciadas por tareas y Cómo: Controlar excepciones en una consulta PLINQ.

Vea también

Referencia

System.Collections.Concurrent

System.Threading

Conceptos

Programación paralela en .NET Framework