2010-01-19 12 views
7

Establecí el hilo máximo en 10. Luego agregué 22000 tareas usando ThreadPool.QueueUserWorkItem. Es muy probable que no se hayan completado todas las 22 000 tareas después de ejecutar el programa. ¿Existe una limitación de cuántas tareas se pueden poner en cola para hilos disponibles?Elementos en cola máximos en ThreadPool.QueueUserWorkItem

Respuesta

6

La cola no tiene ningún límite práctico; sin embargo, el grupo en sí no superará los 64 identificadores de espera, es decir, los hilos totales activos.

+0

Un error causó mi problema, pero básicamente la respuesta a la pregunta es esta. –

+0

Gracias @keith. Por lo tanto, parece que el único límite real para el tamaño de la cola es el tamaño de un objeto genérico de cola (o similar). – matrixugly

+0

¿Qué? ¡Tengo 150 subprocesos de grupo de subprocesos activos! – Vlad

4

Desde el documentation of ThreadPool:

Nota: Las discusiones en el grupo de subprocesos administrados son hilos de fondo. Es decir, sus propiedades IsBackground son verdaderas. Esto significa que un subproceso de ThreadPool no mantendrá una aplicación ejecutándose después de que todos los subprocesos de primer plano hayan salido.

¿Es posible que salga antes de que se hayan procesado todas las tareas?

4

Esta es una pregunta que depende de la implementación y la implementación de esta función ha cambiado un poco con el tiempo. Pero en .Net 4.0, básicamente está limitado por la cantidad de memoria en el sistema, ya que las tareas se almacenan en una cola en la memoria. Puedes ver esto explorando la implementación en reflector.

11

Si necesita esperar a que todas las tareas se procesen, debe manejarlo usted mismo. Los hilos de ThreadPool son todos hilos de fondo y no mantendrán viva la aplicación.

Esta es una manera relativamente limpia para manejar este tipo de situaciones:

using (var mre = new ManualResetEvent(false)) 
{ 
     int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks" 
     foreach(var item in workItems) 
     { 
      // Delegate closure (in C# 4 and earlier) below will 
      // capture a reference to 'item', resulting in 
      // the incorrect item sent to ProcessTask each iteration. Use a local copy 
      // of the 'item' variable instead. 
      // C# 5/VS2012 will not require the local here. 
      var localItem = item; 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       // Replace this with your "work" 
       ProcessTask(localItem); 

       // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done 
       if (Interlocked.Decrement(ref remainingToProcess) == 0) 
         mre.Set(); 
      }); 
     } 
     mre.WaitOne(); 
} 

Dicho esto, por lo general es mejor a "grupo", junto a sus elementos de trabajo si tiene miles de ellos, y no los trate como elementos de trabajo separados para el grupo de temas. Este es un gasto indirecto relacionado con la gestión de la lista de elementos, y como no podrá procesar 22000 a la vez, es mejor agruparlos en bloques. Tener elementos de trabajo individuales cada proceso de 50 probablemente le ayudará bastante a su rendimiento general ...

+0

Buena idea, pero la aplicación estaba esperando todos los hilos. Agrupar es también una muy buena sugerencia. –

Cuestiones relacionadas