Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A System.Threading.ThreadPool classe fornece ao aplicativo um pool de threads de trabalho gerenciados pelo sistema, permitindo que você se concentre em tarefas de aplicativo em vez de gerenciamento de threads. Se você tiver tarefas curtas que exijam processamento em segundo plano, o pool de threads gerenciados será uma maneira fácil de tirar proveito de vários threads. O uso do pool de threads é significativamente mais fácil no Framework 4 e versões posteriores, já que você pode criar objetos Task e Task<TResult> que executam tarefas assíncronas em threads do pool de threads.
O .NET usa threads do pool de threads para muitos fins, incluindo em operações de TPL (Biblioteca de Paralelismo de Tarefas), na conclusão de E/S assíncrona, em retornos de chamada timer, em operações de espera registradas, em chamadas de método assíncrono usando delegados e em conexões de soquete System.Net.
Características do pool de threads
Os threads de pool de threads são threads de segundo plano. Cada thread usa o tamanho da pilha padrão, é executado com prioridade padrão e está no apartamento de vários threads. Depois que um tópico no pool de tópicos concluir sua tarefa, ele será retornado para uma fila de tópicos de espera. A partir deste momento, ele pode ser reutilizado. Essa reutilização permite que os aplicativos evitem o custo de criação de um novo thread para cada tarefa.
Há apenas um pool de threads por processo.
Exceções em threads do pool de threads
Exceções sem tratamento nos threads do pool de threads encerram o processo. Há três exceções a essa regra:
- Um System.Threading.ThreadAbortException é gerado em um thread do pool de threads porque Thread.Abort foi chamado.
- Um System.AppDomainUnloadedException é gerado em um thread do pool de threads porque o domínio do aplicativo está sendo descarregado.
- O common language runtime ou um processo de host encerra o thread.
Para obter mais informações, consulte Exceções em Threads Gerenciados.
Número máximo de threads do pool de threads
O número de operações que podem ser enfileiradas para o pool de threads é limitado apenas pela memória disponível. No entanto, o pool de threads limita o número de threads que podem estar ativos no processo simultaneamente. Se todos os threads do pool de threads estiverem ocupados, itens de trabalho adicionais serão enfileirados até que os threads para os executar se tornem disponíveis. O tamanho padrão do pool de threads para um processo depende de vários fatores, como o tamanho do espaço de endereço virtual. Um processo pode chamar o ThreadPool.GetMaxThreads método para determinar o número de threads.
Você pode controlar o número máximo de threads usando os métodos ThreadPool.GetMaxThreads e ThreadPool.SetMaxThreads.
Observação
O código que hospeda o common language runtime pode definir o tamanho usando o ICorThreadpool::CorSetMaxThreads
método.
Valores mínimos no pool de threads
O pool de threads fornece novos threads de trabalho ou threads de conclusão de E/S sob demanda, até atingir um mínimo especificado para cada categoria. Você pode usar o ThreadPool.GetMinThreads método para obter esses valores mínimos.
Observação
Quando a demanda é baixa, o número real de threads do pool de threads pode ficar abaixo dos valores mínimos.
Quando um mínimo é atingido, o pool de threads pode criar threads adicionais ou aguardar até que algumas tarefas sejam concluídas. O pool de threads cria e destrói threads de trabalho a fim de otimizar a taxa de transferência, que é definida como o número de tarefas concluídas por unidade de tempo. Poucos threads podem não fazer o uso ideal dos recursos disponíveis, enquanto muitos threads podem aumentar a contenção de recursos.
Cuidado
Você pode usar o ThreadPool.SetMinThreads método para aumentar o número mínimo de threads ociosos. No entanto, aumentar desnecessariamente esses valores pode causar problemas de desempenho. Se muitas tarefas começarem ao mesmo tempo, todas elas podem parecer lentas. Na maioria dos casos, o pool de threads terá um desempenho melhor com seu próprio algoritmo de alocação de threads.
Usando o pool de threads
A maneira mais fácil de usar o pool de threads é usar a TPL (Biblioteca Paralela de Tarefas). Por padrão, tipos de TPL como Task e Task<TResult> usam threads do pool de threads para executar tarefas.
Você também pode usar o pool de threads chamando ThreadPool.QueueUserWorkItem de código gerenciado (ou ICorThreadpool::CorQueueUserWorkItem
de código não gerenciado) e passando um System.Threading.WaitCallback delegado que representa o método que executa a tarefa.
Outra maneira de usar o pool de threads é enfileirando itens de trabalho relacionados a uma operação de espera usando o método ThreadPool.RegisterWaitForSingleObject e passando um System.Threading.WaitHandle que, quando sinalizado ou após tempo limite, chama o método representado pelo delegado System.Threading.WaitOrTimerCallback. Os threads do pool de thread são usados para invocar métodos de retorno de chamada.
Para obter os exemplos, verifique as páginas de API referenciadas.
Ignorando verificações de segurança
O pool de threads também fornece os métodos ThreadPool.UnsafeQueueUserWorkItem e ThreadPool.UnsafeRegisterWaitForSingleObject. Use estes métodos somente quando você tiver certeza de que a pilha do chamador é irrelevante a qualquer verificação de segurança executada durante a execução da tarefa em fila. ThreadPool.QueueUserWorkItem e ThreadPool.RegisterWaitForSingleObject capturam a pilha do chamador, que é mesclada na pilha do thread do pool de threads quando o thread começa a executar uma tarefa. Se uma verificação de segurança for necessária, toda a estrutura deverá ser verificada. Embora a verificação forneça segurança, ela também tem um custo de desempenho.
Quando não usar o thread do pool de threads
Há várias situações nas quais é apropriado criar e gerenciar seus próprios threads em vez de usar os threads do pool de threads:
- Você precisa de um thread em primeiro plano.
- Você precisa que um thread tenha uma prioridade específica.
- Há tarefas que causam o bloqueio do thread por longos períodos. O pool de threads tem um número máximo de threads, portanto, a existência de muitos threads do pool de threads bloqueados pode impedir a inicialização das tarefas.
- Você precisa colocar os threads em um apartamento de thread único. Todos os threads ThreadPool estão no apartamento de vários threads.
- Você precisa ter uma identidade estável associada ao thread, ou dedicar um thread a uma tarefa.