Outras respostas aqui parecem estar deixando de fora o ponto mais importante:
A menos que você esteja tentando paralelizar uma operação com uso intensivo de CPU para fazê-la mais rapidamente em um site de baixa carga, não há nenhum ponto em usar um thread de trabalho.
Isso vale para threads livres, criados por new Thread(...)
, e threads de trabalho no ThreadPool
que respondem às QueueUserWorkItem
solicitações.
Sim, é verdade, você pode privar o ThreadPool
processo em um ASP.NET enfileirando muitos itens de trabalho. Isso impedirá que o ASP.NET processe outras solicitações. As informações no artigo são precisas a esse respeito; o mesmo pool de threads usado para QueueUserWorkItem
também é usado para atender a solicitações.
Mas se você está realmente enfileirando itens de trabalho suficientes para causar essa privação, então você deve estar privando o pool de threads! Se você estiver executando literalmente centenas de operações com uso intensivo de CPU ao mesmo tempo, de que adiantaria ter outro thread de trabalho para atender a uma solicitação ASP.NET, quando a máquina já está sobrecarregada? Se você está passando por essa situação, precisa redesenhar completamente!
Na maioria das vezes, vejo ou ouço falar de código multithread sendo usado de maneira inadequada no ASP.NET, não é para enfileirar trabalhos com uso intensivo de CPU. É para enfileirar o trabalho vinculado a E / S. E se você quiser fazer o trabalho de E / S, deve usar um thread de E / S (Porta de Conclusão de E / S).
Especificamente, você deve usar os retornos de chamada assíncronos suportados por qualquer classe de biblioteca que estiver usando. Esses métodos são sempre identificados de forma muito clara; eles começam com as palavras Begin
e End
. Como em Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
e assim por diante.
Estes métodos fazem usar o ThreadPool
, mas eles usam IOCPs, que não não interferem com os pedidos do ASP.NET. Eles são um tipo especial de thread leve que pode ser "ativado" por um sinal de interrupção do sistema de E / S. E em um aplicativo ASP.NET, você normalmente tem um thread de E / S para cada thread de trabalho, portanto, cada solicitação pode ter uma operação assíncrona enfileirada. Isso significa literalmente centenas de operações assíncronas sem qualquer degradação significativa do desempenho (supondo que o subsistema de E / S possa acompanhar). É muito mais do que você precisa.
Apenas tenha em mente que os delegados assíncronos não funcionam dessa maneira - eles acabarão usando um thread de trabalho, assim como ThreadPool.QueueUserWorkItem
. Somente os métodos assíncronos internos das classes da biblioteca do .NET Framework são capazes de fazer isso. Você pode fazer isso sozinho, mas é complicado e um pouco perigoso e provavelmente está além do escopo desta discussão.
A melhor resposta a essa pergunta, em minha opinião, é não usar o ThreadPool
ou uma Thread
instância de plano de fundo no ASP.NET . Não é como criar um thread em um aplicativo Windows Forms, onde você faz isso para manter a IU responsiva e não se preocupa com sua eficiência. No ASP.NET, sua preocupação é a taxa de transferência , e todo esse contexto alternando todos os threads de trabalho irá absolutamente matar sua taxa de transferência, quer você use ThreadPool
ou não.
Por favor, se você está escrevendo um código de threading em ASP.NET - considere se ele pode ou não ser reescrito para usar métodos assíncronos pré-existentes, e se não puder, então considere se você realmente precisa ou não do código para ser executado em um thread em segundo plano. Na maioria dos casos, você provavelmente estará adicionando complexidade sem nenhum benefício líquido.