lunes, 14 de diciembre de 2015

C# Concurrent Collections BlockingCollection

Cuando se trabaja en un ambiente de multihilos. necesita asegurarse de que no esta manipulando datos compartidos al mismo tiempo sin sincronizar el acceso.

.NET Framework ofrece algunas clases de colección que son creadas especificamente para ser usadas en ambientes medioambientes concurrentes como los que se producen cuando se usan lultihilos. estas colecciones ofrecen un ambiente un hilo seguro, lo que significa que internamente usan sincronizacion para hacer seguro el acceso por multiples hilos al mismo tiempo. Las colecciones son :

BlockingCollection<T>
ConcurrentBag<T>
ConcurrentDictionary<TKey, T>
ConcurrentQueue<T>
ConcurrentStack<T>

BlockingCollection<T>
Esta colleccion es un hilo seguro para agregar y remover datos. Remover un elemento desde la coleccion puede ser bloqueada hasta que los datos esten disponibles. Agregar datos es rápido, pero asignar datos puede alcanzar un limite. Si este limite es alcanzado un bloque de elementos lallamada al hilo es realizada hasta se encuentre espacio.

BlockingCollection es en realidad un envoltorio alrededor de otro tipo de colecciones. Si usted no da una alguna instruccion especifica este usa por omision ConcurrentQueue.

Una colección regular levanta un escenario multihilos porque el elemento puede ser removido por otro hilo mientras  el otro hilo estra tratando de leer este.

El siguiente ejemplo usa una coleccion BlockingCollection. Una Task esta preparada para nuevos elementos agregados a la colección. Este bloque es caso de no haber disponibles. La otra tarea agrega elementos a la colección.


using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace UsandoBlockingCollection
{
    class Program
    {
        static void Main(string[] args)
        {
            BlockingCollection<string> col = new BlockingCollection<string>();
            Task read = Task.Run(() =>
            {
                while (true)
                {
                    Console.WriteLine(col.Take());
                }
            });

            Task write = Task.Run(() =>
            {
                while (true)
                {
                    string s = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(s)) break;
                    col.Add(s);
                }
            });

            write.Wait();
        }
    }
}

El programa termina cuando el usuario solo hace ENTER, sin dato. Hasta que, cualquier cadena es colocada es agregada por el Task que escribe y removido por la Task read.




Referencia:
Exam Ref 70-483 Programming in C#




No hay comentarios.:

Publicar un comentario