ThreadPool Classe

Definição

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

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

Exemplos

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

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

   // This thread procedure performs the task.
   static void ThreadProc(Object^ stateInfo)
   {
      
      // No state object was passed to QueueUserWorkItem, so stateInfo is 0.
      Console::WriteLine( "Hello from the thread pool." );
   }
};

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
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 será encerrado 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 acordados 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> 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 de pool de threads. Você faz isso passando o método de um WaitCallback delegado. O delegado tem a assinatura

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

    em state que é 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 .

Observação

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 em 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 tratado 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 tiver sido enfileirado.

Os temporizadores de fila de temporizadores 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 de um processo depende de vários fatores, como o tamanho do espaço de endereço virtual. Um processo pode chamar o método GetMaxThreads 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.

Observação

O código não gerenciado que hospeda o .NET Framework pode alterar o tamanho do pool de threads usando a CorSetMaxThreads função , 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 de 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. A partir do .NET Framework 4, 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. Pouquíssimos threads podem não fazer um uso ideal dos recursos disponíveis, enquanto muitos threads podem aumentar a contenção de recursos.

Observação

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 método GetMinThreads para obter esses valores mínimos.

Cuidado

Você pode usar o SetMinThreads método para aumentar o número mínimo de threads. No entanto, o aumento desnecessário desses 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.

Propriedades

CompletedWorkItemCount

Obtém o número de itens de trabalho que foram processados até agora.

PendingWorkItemCount

Obtém o número de itens de trabalho que estão enfileirados, no momento, para serem processados.

ThreadCount

Obtém o número de threads do pool de threads que existem no momento.

Métodos

BindHandle(IntPtr)
Obsoleto.
Obsoleto.

Associa um identificador de sistema operacional ao ThreadPool.

BindHandle(SafeHandle)

Associa um identificador de 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 método GetMaxThreads(Int32, Int32) e o número de ativos 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 se tornem disponíveis.

GetMinThreads(Int32, Int32)

Recupera 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 mudar para um algoritmo a fim de gerenciar a criação e a destruição de thread.

QueueUserWorkItem(WaitCallback)

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

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 de pool de threads se torna disponível.

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

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

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

Registra um delegado para esperar um WaitHandle, especificando um inteiro com sinal de 32 bits para o tempo limite em milissegundos.

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

Registra um delegado para esperar um WaitHandle, especificando um inteiro 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 valor TimeSpan para o tempo limite.

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

Registra um delegado para aguardar um WaitHandle, especificando um inteiro 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 podem estar ativas simultaneamente. Todas as solicitações acima desse número permanecem na fila até que os threads do pool de threads se tornem 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 mudar para um algoritmo a fim de gerenciar a criação e a destruição de thread.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

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

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

Coloca o objeto de item de trabalho especificado na fila do pool de threads.

UnsafeQueueUserWorkItem(WaitCallback, Object)

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

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

Enfileira um método especificado por um delegado de Action<T> para execução e especifica um objeto que contém os dados a serem usados pelo método. O método é executado quando um thread de pool de threads se torna disponível.

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

Registra um representante para aguardar um WaitHandle, usando um inteiro 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 esperar um WaitHandle, especificando um inteiro 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 valor TimeSpan 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 WaitHandle, especificando um inteiro 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

Este tipo é thread-safe.

Confira também