thread programming parallel net for examples c# .net multithreading parallel-processing

parallel - thread programming c#



ParticiĆ³n de trozos IEnumerable en Parallel.Foreach (2)

Los ejemplos de MSDN para la programación paralela con .NET Framework contienen una implementación de un ChunkPartitioner . Está contenido en el proyecto ParallelExtensionsExtra .

¿Alguien sabe de una manera de obtener el bucle Parallel.Foreach para usar la partición de trozos en comparación con, lo que creo que es la partición de rango por defecto? Parece sencillo cuando se trabaja con matrices porque puede crear un particionador personalizado y establecer el equilibrio de carga en verdadero.

Dado que la cantidad de elementos en un IEnumerable no se conoce hasta el tiempo de ejecución, no puedo encontrar una buena manera de hacer que la partición de trozos funcione.

Cualquier ayuda sería apreciada.

¡Gracias!

Las tareas que estoy tratando de realizar en cada objeto toman tiempos significativamente diferentes para realizar. Al final, generalmente estoy esperando horas para que el último hilo termine su trabajo. Lo que estoy tratando de lograr es tener fragmentos de solicitud de bucle paralelo en el camino en lugar de asignar previamente elementos a cada hilo.


Si su IEnumerable era realmente algo que tenía un indexador (es decir, podría hacer obj[1] para sacar un artículo), podría hacer lo siguiente

var rangePartitioner = Partitioner.Create(0, source.Length); Parallel.ForEach(rangePartitioner, (range, loopState) => { // Loop over each range element without a delegate invocation. for (int i = range.Item1; i < range.Item2; i++) { var item = source[i] //Do work on item } });

Sin embargo, si no puede hacerlo, debe escribir un particionador personalizado creando una nueva clase derivada de System.Collections.Concurrent.Partitioner<TSource> . Ese tema es demasiado amplio para abarcarlo en una respuesta SO, pero puede consultar esta guía en MSDN para comenzar.

ACTUALIZACIÓN: A partir de .NET 4.5, agregaron una Partitioner.Create que no almacena datos en el búfer, tiene el mismo efecto de crear un particionador personalizado con un rango de tamaño máximo de 1. Con esto no obtendrá un solo hilo que un montón de trabajo en cola si tiene mala suerte con un montón de elementos lentos en una fila.

var partitoner = Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering); Parallel.ForEach(partitoner, item => { //Do work }