2012-03-25 17 views
12

Necesito un entorno que necesite mantener diferentes colas de tareas, y que cada una de ellas tenga un número bien definido de subprocesos simultáneos que se puedan ejecutar para cada cola. Algo como esto:C# tarea estrangulamiento de múltiples colas

  • Cola 1 -> 3 hilos;
  • Cola 2 -> 6 hilos;

Tipo de sistema de tarea. Me las he arreglado para implementar esto usando código old plain C# (también conocido como System.Threading.Thread, lock and queue) que funciona más que bien por un año. Sin embargo, sigo leyendo artículos sobre las maravillas de TaskFactory y TaskScheduler, acerca de ser posible esto con las clases integradas en .NET, pero no he podido encontrar un ejemplo para probar esto. Me gustaría probarlo y compararlo con lo que tengo ahora para ver si funciona mejor y, si lo hace, para reemplazarlo.

más, puedo vivir sin tener que limitar/establecer el número de hilos paralelos para cada cola, siempre que puedo conseguir el guarantee que si un artículo destinado para la cola # 2 se ejecuta imediatly incluso si la cola # 1 está ejecutando a plena carga

Entonces, mi pregunta es - ¿hay algo en .NET 4 y más, alguien me puede indicar una muestra? Estoy buscando uno una semana entera y no conseguí algo relevante.

Respuesta

3

Puede intentar crear el equivalente de LimitedConcurrencyLevelTaskScheduler mencionado en this example o consultar el planificador de prioridades mencionado here.

+0

Para lograr lo que el OP parece querer, no es suficiente que las tareas se emitan en una cola de prioridad.Los hilos que ejecutan las tareas en la cola n. ° 2 deben ejecutarse con una prioridad más alta que aquellos que prestan servicio a la cola n. ° 1. No está claro que estas soluciones lo permitan? –

+1

Sí, al parecer esto es lo que coincide con lo que necesito. Implementa colas diferentes y limita el número máximo de elementos que se pueden ejecutar al mismo tiempo y no detiene la segunda cola para ejecutar otros elementos en paralelo con el primero. ¡Gracias! – dcg

6

Esto es realmente bastante trivial usando el TPL y las nuevas colecciones en System.Collections.Concurrent.

Para sus necesidades, el BlockingCollection<T> es lo que recomendaría. De manera predeterminada, utiliza un ConcurrentQueue<T> como la tienda subyacente que es perfecta para lo que desea.

var queue = new BlockingCollection<Message>(); 

Para establecer un código de trabajo en esos mensajes, y controlar cuántos pueden ejecutar en paralelo es tan simple como esto:

//Set max parallel Tasks 
var options = new ParallelOptions 
{ 
    MaxDegreeOfParallelism = 10 
}; 

Parallel.ForEach(queue.GetConsumingEnumerable(), options, msg => 
{ 
    //Do some stuff with this message 
}); 

Entonces, ¿qué está pasando aquí? Bueno ...

La llamada a GetConsumingEnumerable() se bloqueará hasta que haya algo en queue consumido. Esto es genial porque no es necesario un código adicional para indicar que el nuevo trabajo está listo para realizarse. Por el contrario, como se llena queue, una nueva tarea con su delegado (anónimo) se iniciará con un elemento.

El objeto ParallelOptions le permite controlar cómo opera Parallel.ForEach. En este caso, le está diciendo que nunca desea que se ejecuten más de 10 tareas al mismo tiempo. ¡Es importante tener en cuenta que Tareas! = Hilos. Los detalles son turbios, pero no hace falta decir que hay una gran cantidad de optimización bajo el capó. Es todo enchufable, pero no es para corazones débiles.

Obviamente, hay muchos detalles que no he tratado aquí, pero espero que pueda ver cuán simple y expresivo puede ser el uso de la Biblioteca de tareas paralelas.

+0

El OP parece necesitar una cola de prioridad y subprocesos de prioridad para ejecutar primero los elementos en la cola n. ° 2. –

+2

Esa no es la impresión que tengo. Simplemente indicó que necesita poder controlar el número de tareas concurrentes para que ninguna cola consuma todos los recursos. La solución anterior puede ampliarse fácilmente teniendo múltiples colas. Llenar esas colas depende de él, pero es bastante fácil controlar cuántas tareas se pueden ejecutar en paralelo de esta manera. Uno con 50, otro con 10, etc ... – Josh