ThreadPool Classe

Definição

Fornece um pool de threads que podem ser usados para executar tarefas, pós-itens de trabalho, processar E/S assíncrona, aguardar em nome de outros threads e temporizadores de processo.

public ref class ThreadPool sealed
public ref class ThreadPool abstract sealed
public sealed class ThreadPool
public static class ThreadPool
type ThreadPool = class
Public NotInheritable Class ThreadPool
Public Class ThreadPool
Herança
ThreadPool

Exemplos

No exemplo a seguir, o thread do aplicativo principal enfileira um método nomeado ThreadProc para executar em um thread do pool de threads, dorme por um segundo e, em seguida, sai. O ThreadProc método simplesmente exibe uma mensagem.

using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) 
    {
        // No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Queue the work for execution.
        ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
        
        Console.WriteLine("Main thread does some work, then sleeps.")

        Thread.Sleep(1000)

        Console.WriteLine("Main thread exits.")
    End Sub

    ' This thread procedure performs the task.
    Sub ThreadProc(stateInfo As Object)
        ' No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.")
    End Sub
End Module
' The example displays output like the following:
'       Main thread does some work, then sleeps.
'       Hello from the thread pool.
'       Main thread exits.

Se você comentar a chamada para o Thread.Sleep método, o thread principal sairá antes que o método seja executado no thread do pool de threads. O pool de threads usa threads em segundo plano, que não mantêm o aplicativo em execução se todos os threads em primeiro plano tiverem sido encerrados. (Este é um exemplo simples de uma condição de corrida.)

Comentários

Muitos aplicativos criam threads que passam muito tempo no estado de suspensão, aguardando que um evento ocorra. Outros threads podem entrar em um estado de suspensão apenas para serem despertados periodicamente para sondar uma alteração ou atualizar informações de status. O pool de threads permite que você use threads com mais eficiência fornecendo ao aplicativo um pool de threads de trabalho gerenciados pelo sistema. Exemplos de operações que usam threads de pool de threads incluem o seguinte:

  • Quando você cria um Task objeto ou Task<TResult> um objeto para executar alguma tarefa de forma assíncrona, por padrão, a tarefa é agendada para ser executada em um thread do pool de threads.

  • Os temporizadores assíncronos usam o pool de threads. Os threads do pool de threads executam retornos de chamada da System.Threading.Timer classe e geram eventos da System.Timers.Timer classe.

  • Quando você usa identificadores de espera registrados, um thread do sistema monitora o status dos identificadores de espera. Quando uma operação de espera é concluída, um thread de trabalho do pool de threads executa a função de retorno de chamada correspondente.

  • Quando você chama o QueueUserWorkItem método para enfileirar um método para execução em um thread do pool de threads. Você faz isso passando o método a um WaitCallback delegado. O delegado tem a assinatura

    void WaitCallback(Object state)
    
    Sub WaitCallback(state As Object)
    

    onde state está um objeto que contém dados a serem usados pelo delegado. Os dados reais podem ser passados para o delegado chamando o QueueUserWorkItem(WaitCallback, Object) método.

Note

Os threads no pool de threads gerenciados são threads em segundo plano. Ou seja, suas IsBackground propriedades são true. Isso significa que um ThreadPool thread não manterá um aplicativo em execução depois que todos os threads de primeiro plano tiverem sido encerrados.

Importante

Quando o pool de threads reutiliza um thread, ele não limpa os dados no armazenamento local do thread ou em campos marcados com o ThreadStaticAttribute atributo. Portanto, quando um método examina o armazenamento local do thread ou os campos marcados com o ThreadStaticAttribute atributo, os valores encontrados podem ser deixados de um uso anterior do thread do pool de threads.

Você também pode enfileirar itens de trabalho que não estão relacionados a uma operação de espera para o pool de threads. Para solicitar que um item de trabalho seja manipulado por um thread no pool de threads, chame o QueueUserWorkItem método. Esse método usa como parâmetro uma referência ao método ou delegado que será chamado pelo thread selecionado no pool de threads. Não há como cancelar um item de trabalho depois que ele foi enfileirado.

Os temporizadores de fila de temporizador e as operações de espera registradas também usam o pool de threads. Suas funções de retorno de chamada são enfileiradas no pool de threads.

Há um pool de threads por processo. A partir do .NET Framework 4, 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 GetMaxThreads método para determinar o número de threads. O número de threads no pool de threads pode ser alterado usando o SetMaxThreads método. Cada thread usa o tamanho da pilha padrão e é executado na prioridade padrão.

Note

O código não gerenciado que hospeda o .NET Framework pode alterar o tamanho do pool de threads usando a função CorSetMaxThreads, definida no arquivo mscoree.h.

O pool de threads fornece novos threads de trabalho ou threads de conclusão de E/S sob demanda até atingir o máximo para cada categoria. Quando um máximo é atingido, o pool de threads pode criar threads adicionais nessa categoria ou aguardar até que algumas tarefas sejam concluídas. Começando com o .NET Framework 4, 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 que são 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.

Note

Quando a demanda é baixa, o número real de threads do pool de threads pode ficar abaixo dos valores mínimos.

Você pode usar o GetMinThreads método para obter esses valores mínimos.

Caution

Você pode usar o SetMinThreads método para aumentar o número mínimo de threads. 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.

Métodos

Nome Description
BindHandle(IntPtr)
Obsoleto.

Associa um identificador do sistema operacional ao ThreadPool.

BindHandle(SafeHandle)

Associa um identificador do sistema operacional ao ThreadPool.

GetAvailableThreads(Int32, Int32)

Recupera a diferença entre o número máximo de threads do pool de threads retornados pelo GetMaxThreads(Int32, Int32) método e o número ativo no momento.

GetMaxThreads(Int32, Int32)

Recupera o número de solicitações para o pool de threads que podem estar ativas simultaneamente. Todas as solicitações acima desse número permanecem na fila até que os threads do pool de threads fiquem disponíveis.

GetMinThreads(Int32, Int32)

Recupera o número mínimo de threads que o pool de threads cria sob demanda, conforme novas solicitações são feitas, antes de alternar para um algoritmo para gerenciar a criação e a destruição de threads.

QueueUserWorkItem(WaitCallback, Object)

Enfileira um método para execução e especifica um objeto que contém dados a serem usados pelo método. O método é executado quando um thread do pool de threads fica disponível.

QueueUserWorkItem(WaitCallback)

Enfileira um método para execução. O método é executado quando um thread do pool de threads fica disponível.

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Enfileira um método especificado por um Action<T> delegado para execução e fornece dados a serem usados pelo método. O método é executado quando um thread do pool de threads fica disponível.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro com sinal de 32 bits para o tempo limite em milissegundos.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro com sinal de 64 bits para o tempo limite em milissegundos.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Registra um delegado para aguardar um WaitHandle, especificando um TimeSpan valor para o tempo limite.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro sem sinal de 32 bits para o tempo limite em milissegundos.

SetMaxThreads(Int32, Int32)

Define o número de solicitações para o pool de threads que pode estar ativo simultaneamente. Todas as solicitações acima desse número permanecem na fila até que os threads do pool de threads fiquem disponíveis.

SetMinThreads(Int32, Int32)

Define o número mínimo de threads que o pool de threads cria sob demanda, à medida que novas solicitações são feitas, antes de alternar para um algoritmo para gerenciar a criação e a destruição de threads.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

Enfileira uma operação de E/S sobreposta para execução.

UnsafeQueueUserWorkItem(WaitCallback, Object)

Enfileira o delegado especificado para o pool de threads, mas não propaga a pilha de chamadas para o thread de trabalho.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro com sinal de 32 bits para o tempo limite em milissegundos. Esse método não propaga a pilha de chamadas para o thread de trabalho.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro com sinal de 64 bits para o tempo limite em milissegundos. Esse método não propaga a pilha de chamadas para o thread de trabalho.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Registra um delegado para aguardar um WaitHandle, especificando um TimeSpan valor para o tempo limite. Esse método não propaga a pilha de chamadas para o thread de trabalho.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Registra um delegado para aguardar um WaitHandleinteiro sem sinal de 32 bits para o tempo limite em milissegundos. Esse método não propaga a pilha de chamadas para o thread de trabalho.

Aplica-se a

Acesso thread-safe

Esse tipo é thread safe.

Confira também