Partilhar via


O pool de threads gerenciado

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 você tiver tarefas curtas que exigem processamento em segundo plano, o pool de threads gerenciados é uma maneira fácil de aproveitar vários threads. O uso do pool de threads é significativamente mais fácil no Framework 4 e posterior, pois você pode criar Task e Task<TResult> objetos que executam tarefas assíncronas em threads de pool de threads.

O .NET usa threads de pool de threads para muitas finalidades, incluindo operações TPL (Task Parallel Library), conclusão assíncrona de E/S, retornos de chamada de temporizador , operações de espera registradas, chamadas de método assíncronas usando delegados e System.Net conexões de soquete.

Características do pool de roscas

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 sua tarefa, ele retorna a 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 threads de pool de threads

Exceções não tratadas em threads de pool de threads encerram o processo. Existem três exceções a esta regra:

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, os itens de trabalho adicionais serão enfileirados até que os threads para executá-los 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 ThreadPool.GetMaxThreads métodos and ThreadPool.SetMaxThreads .

Nota

O código que hospeda o Common Language Runtime pode definir o tamanho usando o ICorThreadpool::CorSetMaxThreads método.

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.

Nota

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 para 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.

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 gostam Task e Task<TResult> usam threads de 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 é enfileirar itens de trabalho relacionados a uma operação de espera usando o ThreadPool.RegisterWaitForSingleObject método e passando um System.Threading.WaitHandle que, quando sinalizado ou quando expirado, chama o método representado pelo System.Threading.WaitOrTimerCallback delegado. Os threads do pool de threads são usados para invocar métodos de retorno de chamada.

Para os exemplos, verifique as páginas de API referenciadas.

Ignorar verificações de segurança

O pool de threads também fornece os ThreadPool.UnsafeQueueUserWorkItem métodos e ThreadPool.UnsafeRegisterWaitForSingleObject . Use esses métodos somente quando tiver certeza de que a pilha do chamador é irrelevante para quaisquer verificações de segurança realizadas durante a execução da tarefa enfileirada. ThreadPool.QueueUserWorkItem e ThreadPool.RegisterWaitForSingleObject ambos 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 for necessária uma verificação de segurança, toda a pilha deve ser verificada. Embora a verificação proporcione segurança, também tem um custo de desempenho.

Quando não usar threads de pool de threads

Há vários cenários em que é apropriado criar e gerenciar seus próprios threads em vez de usar threads de pool de threads:

  • 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 thread ou dedicar um thread a uma tarefa.

Consulte também