Como: Usar um pool thread (guia de programação translation from VPE for Csharp)

A pool de segmentos é uma coleção de segmentos que podem ser usados para executar várias tarefas no plano de fundo.(See Usando o Threading (guia de programação translation from VPE for Csharp) Para obter mais informações.) Isso deixa o thread primário disponível para executar Outros tarefas de forma assíncrona.

Thread pools normalmente são empregados em programas servidores.Cada solicitação que chega é atribuída a uma thread do pool de threads, para que a solicitação pode ser processada de forma assíncrona, sem interromper a thread principal ou atrasar o processamento de solicitações subsequentes.

Depois que a thread do pool concluir sua tarefa, ela retorna para a fila de threads em modo de espera, onde a thread pode ser reutilizada.Essa reutilização permite que os programas evitem o custo de criar uma nova thread cada tarefa.

Thread pools geralmente tem um número máximo de threads.Se todas as threads estiverem ocupadas, tarefas adicionais serão colocadas na fila até que elas possam ser atendidas a medida que as threads se tornarem disponíveis.

Você pode implementar seu próprio thread pool, mas é mais fácil de usar o thread pool fornecido pelo .NET estrutura por meio de ThreadPool classe.

O exemplo a seguir usa o .NET estrutura thread pool para calcular o Fibonacci resultado de dez números entre 20 e 40. Cada Fibonacci resultado é representado pela Fibonacci classe, que fornece um método chamado ThreadPoolCallback que executará o cálculo. Um objeto que representa cada Fibonacci valor é criado e o ThreadPoolCallback método é passado para QueueUserWorkItem, que atribui um segmento disponível no pool para executar o método.

Como cada Fibonacci objeto recebe um valor semi-random para calcular e como cada thread irá ser competindo pelo time do processador, não se pode saber antecipadamente quanto time levará para todos os dez resultados deve ser calculado. É por isso que cada Fibonacci objeto é passado a uma instância das ManualResetEvent classe durante a construção. Cada objeto sinaliza o objeto de evento fornecidos quando o cálculo é concluído, que permite que o thread principal para execução de bloco com WaitAll até que todos os dez Fibonacci objetos calculou um resultado. The Main método, em seguida, exibe cada Fibonacci resultado.

Exemplo

using System;
using System.Threading;

public class Fibonacci
{
    public Fibonacci(int n, ManualResetEvent doneEvent)
    {
        _n = n;
        _doneEvent = doneEvent;
    }

    // Wrapper method for use with thread pool.
    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine("thread {0} started...", threadIndex);
        _fibOfN = Calculate(_n);
        Console.WriteLine("thread {0} result calculated...", threadIndex);
        _doneEvent.Set();
    }

    // Recursive method that calculates the Nth Fibonacci number.
    public int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }

        return Calculate(n - 1) + Calculate(n - 2);
    }

    public int N { get { return _n; } }
    private int _n;

    public int FibOfN { get { return _fibOfN; } }
    private int _fibOfN;

    private ManualResetEvent _doneEvent;
}

public class ThreadPoolExample
{
    static void Main()
    {
        const int FibonacciCalculations = 10;

        // One event is used for each Fibonacci object
        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
        Random r = new Random();

        // Configure and launch threads using ThreadPool:
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
        for (int i = 0; i < FibonacciCalculations; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);
            fibArray[i] = f;
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
        }

        // Wait for all threads in pool to calculation...
        WaitHandle.WaitAll(doneEvents);
        Console.WriteLine("All calculations are complete.");

        // Display the results...
        for (int i= 0; i<FibonacciCalculations; i++)
        {
            Fibonacci f = fibArray[i];
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
        }
    }
}

Aqui está a saída:

launching 10 tasks...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
all calculations complete
Fibonacci(22) = 17711
Fibonacci(25) = 75025
Fibonacci(32) = 2178309
Fibonacci(36) = 14930352
Fibonacci(32) = 2178309
Fibonacci(26) = 121393
Fibonacci(35) = 9227465
Fibonacci(23) = 28657
Fibonacci(39) = 63245986
Fibonacci(22) = 17711

Consulte também

Tarefas

Exemplo de tecnologia de sincronização do Monitor

Aguarde sincronização Tecnologia Exemplo

Conceitos

Guia de Programação C#

Monitores

Referência

Segmentação (guia de programação C#)

Usando o Threading (guia de programação translation from VPE for Csharp)

Mutex

WaitAll

ManualResetEvent

Set

ThreadPool

QueueUserWorkItem

ManualResetEvent

Outros recursos

COMO: Sincronizar o acesso a um recurso compartilhado em um ambiente de multithreading usando Visual .NET translation from VPE for Csharp

Segurança no .NET Framework