Otras respuestas aquí parecen estar omitiendo el punto más importante:
A menos que esté tratando de paralelizar una operación con uso intensivo de CPU para hacerlo más rápido en un sitio de baja carga, no tiene sentido usar un hilo de trabajo en absoluto.
Eso se aplica tanto a los hilos libres, creados por new Thread(...)
, como a los hilos de trabajo en el ThreadPool
que responden a las QueueUserWorkItem
solicitudes.
Sí, es cierto, puede matar de hambre ThreadPool
en un proceso ASP.NET poniendo en cola demasiados elementos de trabajo. Evitará que ASP.NET procese más solicitudes. La información del artículo es precisa a ese respecto; el mismo grupo de subprocesos utilizado QueueUserWorkItem
también se utiliza para atender solicitudes.
Pero si realmente está haciendo cola suficientes elementos de trabajo para causar esta inanición, ¡entonces debería estar privando al grupo de subprocesos! Si está ejecutando literalmente cientos de operaciones con uso intensivo de la CPU al mismo tiempo, ¿de qué le serviría tener otro hilo de trabajo para atender una solicitud ASP.NET, cuando la máquina ya está sobrecargada? Si se encuentra en esta situación, ¡debe rediseñarlo por completo!
La mayoría de las veces que veo o escucho que el código multiproceso se usa de manera inapropiada en ASP.NET, no es para poner en cola el trabajo intensivo de la CPU. Es para poner en cola trabajos vinculados a E / S. Y si desea realizar un trabajo de E / S, debería utilizar un hilo de E / S (puerto de finalización de E / S).
Específicamente, debería usar las devoluciones de llamada asíncronas compatibles con cualquier clase de biblioteca que esté usando. Estos métodos siempre están etiquetados con mucha claridad; comienzan con las palabras Begin
y End
. Al igual que en Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
, y así sucesivamente.
Estos métodos hacen uso de la ThreadPool
, pero utilizan IOCPs, que no no interfieren con las solicitudes de ASP.NET. Son un tipo especial de hilo ligero que se puede "despertar" mediante una señal de interrupción del sistema de E / S. Y en una aplicación ASP.NET, normalmente tiene un subproceso de E / S para cada subproceso de trabajo, por lo que cada solicitud puede tener una operación asíncrona en cola. Eso es literalmente cientos de operaciones asíncronas sin ninguna degradación significativa del rendimiento (asumiendo que el subsistema de E / S puede mantenerse al día). Es mucho más de lo que necesitará.
Solo tenga en cuenta que los delegados asíncronos no funcionan de esta manera; terminarán usando un hilo de trabajo, como ThreadPool.QueueUserWorkItem
. Solo los métodos asíncronos integrados de las clases de biblioteca de .NET Framework son capaces de hacer esto. Puede hacerlo usted mismo, pero es complicado y un poco peligroso y probablemente más allá del alcance de esta discusión.
La mejor respuesta a esta pregunta, en mi opinión, es no usar ThreadPool
o una Thread
instancia en segundo plano en ASP.NET . No es en absoluto como hacer girar un hilo en una aplicación de Windows Forms, donde lo hace para mantener la interfaz de usuario receptiva y no le importa cuán eficiente sea. En ASP.NET, su preocupación es el rendimiento , y todo ese cambio de contexto en todos esos subprocesos de trabajo va a matar absolutamente su rendimiento, ya sea que use ThreadPool
o no.
Por favor, si se encuentra escribiendo código de subprocesamiento en ASP.NET, considere si se puede reescribir o no para usar métodos asincrónicos preexistentes, y si no puede, considere si realmente necesita el código o no para ejecutarse en un hilo de fondo. En la mayoría de los casos, probablemente agregará complejidad sin ningún beneficio neto.