2012-09-11 13 views
7

Tengo una lista de números de cuenta. Número de cuenta de Foreach Necesito llamar al método ProcessAccount. Habrá aproximadamente 150,000 cuentas que deben procesarse y cada cuenta puede tardar entre .5 y 2 segundos en procesarse.¿Forma fácil de procesar la cola con N hilos en C#?

Me gustaría configurar el enhebrado de alguna manera para poder procesar 4 cuentas a la vez, por ejemplo.

¿Hay un patrón simple que pueda usar para esto?

Lo que me gustaría hacer es iniciar 4 subprocesos procesando las primeras 4 cuentas, y luego, cuando termine cada subproceso, iniciar otro subproceso con la siguiente cuenta hasta que todas las cuentas hayan sido procesadas.

+0

FYI - Lo más probable es estar en ejecución de una aplicación de consola. – AWeim

+4

¿Cuál es la dependencia de 'ProcessAccount'? ¿Es esto una operación de cálculo o una operación de enlace de E/S? –

+1

Bryan tiene un buen punto allí, mencionas una lista, ¿es eso una lista ? Si necesita leer datos del disco, llamar a servicios remotos o algo, las cosas son muy diferentes de cuando tiene todos los datos que necesita en la memoria. Para acelerar las cosas, primero debe identificar su cuello de botella – gjvdkamp

Respuesta

12

Esto es fácil de manejar con TPL (Task Parallel Library). Se vería algo así como

ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; 
Parallel.ForEach(accounts, options, a => 
{ 
    ProcessAccount(a); 
}); 

http://msdn.microsoft.com/en-us/library/dd782721.aspx

Tenga en cuenta que el TPL podría decidir ejecutar menos de 4 hilos concurrentes, pero no se ejecutará más de 4 basado en las opciones especificadas. Podría hacer eso, por ejemplo, si determina que la lamda proporcionada (que llama a ProcessAccount) está unida a la CPU y que hay menos de 4 núcleos de CPU en el sistema. Generalmente, especialmente en .NET 4.5, el TPL toma muy buenas decisiones sobre el número de subprocesos que se utilizarán.

Como @Servy notas en los comentarios, a menos que tenga una razón muy específica para limitar el código a 4 hilos, lo mejor es dejar que TPL sepa cuántos hilos usar por sí solo. De esta forma, si el mismo código se ejecuta en un procesador de 128 núcleos en el año 2018, mucho después de que pase a otras cosas, es gratis usar los 128 núcleos).

+1

A menos que desee limitar intencionalmente los recursos consumidos para dejarlos disponibles para otros, generalmente es mejor no especificar más de lo que necesita. Mientras más libertad le dé a la biblioteca para hacer lo que cree que es apropiado, mejor funcionará. – Servy

+0

@Servy: ese es un muy buen punto. De acuerdo 100% –

1

Uso PLINQ:

var accounts = //some 150,000 account numbers 
accounts.AsParallel().ForAll(ProcessAccount); 

o, si se requieren otros argumentos, utilice una expresión lambda:

accounts.AsParallel().ForAll(account => ProcessAccount(account, argument2, argument3)); 
+0

Esto no limita el número máximo de hilos a 4. –

+1

@EricJ. no, tienes razón, no es así. En mi experiencia, PLinq hace un buen trabajo de estrangulamiento sin ayuda mía, pero no estoy en un territorio extremadamente sensible al rendimiento. – phoog

+1

@EricJ. Supongo que el OP no está familiarizado con el concepto de un grupo de subprocesos (y se espera que tenga que hacer el suyo con un número estático de subprocesos) y no tiene un requisito comercial de restringirlo a 4 subprocesos. – Servy

Cuestiones relacionadas