Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
A System.Threading.ThreadPool classe fornece ao seu aplicativo um pool de threads de trabalho que são gerenciados pelo sistema, permitindo que você se concentre em tarefas de aplicativo em vez de gerenciamento de threads. Se tiveres tarefas curtas que exijam processamento em segundo plano, o pool de threads geridos é uma maneira fácil de tirar partido de vários threads. O uso do pool de threads é significativamente mais fácil no Framework 4 e posterior, uma vez que é possível criar Task e Task<TResult> objetos que executam tarefas assíncronas em threads no pool de threads.
O .NET utiliza threads de pool para várias finalidades, incluindo operações da Biblioteca de Paralelismo de Tarefas (TPL), conclusão assíncrona de I/O, chamadas de retorno de timer, operações de espera registadas, chamadas de métodos assíncronos usando delegados, e conexões de sockets System.Net.
Características do thread pool
Os threads do pool de threads são threads em segundo plano. Cada thread usa o tamanho de pilha padrão, é executado na prioridade padrão e está no apartamento multithreaded. Quando um thread no pool de threads conclui a sua tarefa, é retornado para uma fila de threads em espera. A partir deste momento pode ser reutilizado. Essa reutilização permite que os aplicativos evitem o custo de criar um novo thread para cada tarefa.
Há apenas um pool de threads por processo.
Exceções em gerenciador de threads
Exceções não tratadas em threads do pool de threads encerram o processo. Existem três exceções a esta regra:
- A System.Threading.ThreadAbortException é lançada numa thread do pool de threads porque Thread.Abort foi chamado.
- A System.AppDomainUnloadedException é lançado em um thread do pool de threads porque o domínio da aplicação 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 no pool
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 todas as threads do pool de threads estiverem ocupadas, as tarefas adicionais serão enfileiradas até que as threads para execução fiquem 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 do 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 procura é baixa, o número real de threads no pool 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 thread pool cria e destrói threads de trabalho para otimizar a rendição, 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.
Atenção
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 para alocar threads.
Usando o pool de threads
A maneira mais fácil de usar o pool de threads é usar a TPL (Task Parallel Library). Por padrão, tipos 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 representando o método que executa a tarefa.
Outra maneira de usar o pool de threads é colocar na fila 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 quando ocorre um timeout, chama o método representado pelo delegado System.Threading.WaitOrTimerCallback. Os threads do pool de threads são usados para invocar métodos de callback.
Para os exemplos, verifique as páginas de API referenciadas.
Ignorar verificações de segurança
O pool de threads também fornece os métodos ThreadPool.UnsafeQueueUserWorkItem e ThreadPool.UnsafeRegisterWaitForSingleObject. Utilize estes métodos somente quando tiver certeza de que o stack do chamador é irrelevante para quaisquer verificações de segurança efetuadas no decorrer da execução da tarefa enfileirada. ThreadPool.QueueUserWorkItem e ThreadPool.RegisterWaitForSingleObject capturam a pilha do chamador, que é integrada na pilha da thread da pool de threads quando a thread começa a executar uma tarefa. Se for necessária uma verificação de segurança, deve ser verificada toda a pilha. Embora a verificação proporcione segurança, também tem um custo de desempenho.
Quando não usar threads de grupo de threads
Há vários cenários em que é apropriado criar e gerir os seus próprios threads em vez de usar threads do pool.
- Você precisa de um thread de primeiro plano.
- Você precisa de um thread para ter uma prioridade específica.
- Você tem tarefas que fazem com que o thread bloqueie por longos períodos de tempo. O pool de threads tem um número máximo de threads, portanto, um grande número de threads bloqueados pode impedir que as tarefas sejam iniciadas.
- Você precisa colocar fios em um apartamento de fio único. Todos os ThreadPool fios estão no apartamento multithreaded.
- Você precisa ter uma identidade estável associada ao tópico ou dedicar um tópico a uma tarefa.