ThreadPool.QueueUserWorkItem frente a Task.Factory.StartNew

79

cuál es la diferencia entre los siguientes

ThreadPool.QueueUserWorkItem

vs

Task.Factory.StartNew

Si el código anterior se llama 500 veces para alguna tarea de larga ejecución, ¿significa que se ocuparán todos los subprocesos del grupo de subprocesos?

¿O será TPL (segunda opción) lo suficientemente inteligente como para tomar subprocesos menores o iguales a la cantidad de procesadores?

stackoverflowuser
fuente

Respuestas:

93

Si va a iniciar una tarea de ejecución prolongada con TPL, debe especificar TaskCreationOptions.LongRunning, lo que significa que no la programa en el grupo de subprocesos. (EDITAR: como se señaló en los comentarios, esta es una decisión específica del programador, y no es una garantía dura y rápida, pero espero que cualquier programador de producción sensato evite programar tareas de larga ejecución en un grupo de subprocesos).

Definitivamente, no debería programar una gran cantidad de tareas de larga duración en el grupo de subprocesos. Creo que en estos días el tamaño predeterminado del grupo de subprocesos es bastante grande (porque a menudo se abusa de esta manera) pero fundamentalmente no debería usarse así.

El objetivo del grupo de subprocesos es evitar que las tareas cortas reciban un gran impacto al crear un nuevo subproceso, en comparación con el tiempo que realmente se están ejecutando. Si la tarea se ejecutará durante mucho tiempo, el impacto de crear un nuevo subproceso será relativamente pequeño de todos modos, y no querrás terminar potencialmente quedando sin subprocesos del grupo de subprocesos. (Es menos probable ahora, pero lo experimenté en versiones anteriores de .NET).

Personalmente, si tuviera la opción, sin duda utilizar TPL con el argumento de que la TaskAPI es bastante agradable - pero no recuerde decirle TPL que se espera que la tarea se ejecute durante mucho tiempo.

EDITAR: Como se señaló en los comentarios, consulte también la publicación del blog del equipo de PFX sobre cómo elegir entre el TPL y el grupo de subprocesos :

En conclusión, reiteraré lo que el desarrollador de ThreadPool del equipo de CLR ya ha dicho:

Task is now the preferred way to queue work to the thread pool.

EDITAR: También de los comentarios, no olvide que TPL le permite usar programadores personalizados , si realmente desea ...

Jon Skeet
fuente
4
Soy cauteloso con la regla dura y rápida que TaskCreationOptions.LongRunningsiempre evitará el grupo de subprocesos. Parece ser más una directiva que una garantía de implementación. ¿Estoy fuera de base en eso?
Marc
1
@Marc: Bueno, depende del programador, pero sería un programador bastante loco programar explícitamente tareas de larga duración en el grupo de subprocesos, en mi opinión.
Jon Skeet
Solo para agregar un poco más de información: blogs.msdn.com/b/pfxteam/archive/2009/10/06/9903475.aspx
Brad Semrad
@Brad: Gracias, agregaré un enlace a mi respuesta.
Jon Skeet
1
También agregaría que TPL le permite especificar su propio programador, incluidos programadores personalizados que le permiten controlar su propia concurrencia: msdn.microsoft.com/en-us/library/ee789351.aspx
Chris Shain