Como: Criar e terminar threads (guia de programação translation from VPE for Csharp)

Este exemplo demonstra como um auxiliar ou thread de trabalho podem ser criados e usados para executar o processamento em paralelo com o segmento principal.Um thread tornar um thread aguardar outra e normalmente terminação também são demonstradas.Para obter mais informações sobre consulte Multithreading, Threads gerenciadas e Usando o Threading (guia de programação translation from VPE for Csharp).

O exemplo cria uma classe chamada Worker que contém o método DoWork, que o thread de trabalho será executar. Isso é essencialmente o Main função para o thread de trabalho. O thread de trabalho comece a chamar esse método de execução e terminar automaticamente quando esse método retorna.The DoWork método tem esta aparência:

public void DoWork()
{
    while (!_shouldStop)
    {
        Console.WriteLine("worker thread: working...");
    }
    Console.WriteLine("worker thread: terminating gracefully.");
}

The Worker classe contém um método adicional que é usado para indicar ao DoWork Se ele deve retornar. Este método é chamado RequestStope aparência como esta:

public void RequestStop()
{
    _shouldStop = true;
}

The RequestStop método simplesmente atribui o _shouldStop membro de dados para true. Porque esse membro de dados está com check-pelo DoWork método, isso tem o efeito indireto de causar DoWork para retornar, que termina o thread de trabalho. No entanto, você deve observar que DoWork e RequestStop será executado por threads diferentes. DoWork é executado por thread de trabalho, e RequestStop é executado pelo thread principal, para que o _shouldStop membro de dados é declarado volatile, como este:

private volatile bool _shouldStop;

The volatile o compilador irão vários threads de alertas de palavra-chave acesso o _shouldStop membro de dados e, portanto, ele não devem fazer suposições sobre o estado desse membro otimização. Para obter mais informações, consulte volátil (translation from VPE for Csharp Reference).

O uso de volatile com o _shouldStop membro de dados permite que você acesse com segurança esse membro de vários threads sem o uso de técnicas de sincronização de thread formal, mas somente porque _shouldStop é um bool. Isso significa que operações atômicas apenas única são necessárias para modificar _shouldStop. Se, no entanto, esse membro de dados fosse uma classe, struct ou array, acessá-lo de vários threads causaria provavelmente corrupção de dados intermitentes.Considere a possibilidade de um thread que altera os valores em uma matriz.Windows interrompe regularmente threads para permitir que outros threads executar.Portanto, isso thread pôde ser interrompido após atribuindo alguns elementos da matriz, mas antes de atribuir outras pessoas.Como o array tem agora um estado que o programador nunca se destina, outro thread que lê essa matriz pode falhar.

Antes de realmente criar o thread de trabalho, a Main função cria uma Worker objeto e uma instância do Thread. O objeto thread está configurado para usar o Worker.DoWork o método sistema autônomo um ponto de entrada, passando uma referência a esse método para o Thread construtor, sistema autônomo este:

Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);

Neste ponto, embora o objeto de segmento de trabalho existe e está configurado, o thread de trabalho real não ainda foi criado.Isso não ocorre até Main chamadas a Start método:

workerThread.Start();

Neste ponto o sistema inicia a execução do thread de trabalho, mas não tão assíncrona para o segmento principal.Isso significa que o Main função continua a executar código imediatamente enquanto o thread de trabalho simultaneamente é submetido a inicialização. Para garantir que o Main função não tenta terminar o thread de trabalho antes que ele tem a oportunidade de executar, o Main função faz um loop até que o IsAlive propriedade do objeto segmento de trabalho é definida como true:

while (!workerThread.IsAlive);

Em seguida, o thread principal é interrompido brevemente com uma telefonar para Sleep. Isso garante que o thread de trabalho's DoWork função executará o loop dentro do DoWork método para várias iterações antes da Main função executa mais comandos:

Thread.Sleep(1);

Depois de um milissegundo ter decorrido, Main sinais para o operador thread objeto deve terminar usando o Worker.RequestStop método apresentado anteriormente:

workerObject.RequestStop();

Também é possível terminar um segmento de outro segmento usando uma telefonar de Abort. Isso força termina o thread afetado mesmo se ele não concluiu sua tarefa e não oferece nenhuma oportunidade para a limpeza de recursos.A técnica mostrada neste exemplo é preferida.

Finalmente, a Main chamadas de função a Join método no thread de trabalho objeto. Esse método faz com que o thread corrente bloquear ou esperar, até que o thread que representa o objeto seja encerrado.Portanto, Join não retornará até que o operador de thread retorna, encerrando próprio assim:

workerThread.Join();

Neste ponto, somente o primário de thread em execução Main existe. Ele exibe uma mensagem final e, em seguida, retorna, encerrando o segmento principal também.

Aqui está o exemplo completo.

Exemplo

using System;
using System.Threading;

public class Worker
{
    // This method will be called when the thread is started.
    public void DoWork()
    {
        while (!_shouldStop)
        {
            Console.WriteLine("worker thread: working...");
        }
        Console.WriteLine("worker thread: terminating gracefully.");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Volatile is used as hint to the compiler that this data
    // member will be accessed by multiple threads.
    private volatile bool _shouldStop;
}

public class WorkerThreadExample
{
    static void Main()
    {
        // Create the thread object. This does not start the thread.
        Worker workerObject = new Worker();
        Thread workerThread = new Thread(workerObject.DoWork);

        // Start the worker thread.
        workerThread.Start();
        Console.WriteLine("main thread: Starting worker thread...");

        // Loop until worker thread activates.
        while (!workerThread.IsAlive);

        // Put the main thread to sleep for 1 millisecond to
        // allow the worker thread to do some work:
        Thread.Sleep(1);

        // Request that the worker thread stop itself:
        workerObject.RequestStop();

        // Use the Join method to block the current thread 
        // until the object's thread terminates.
        workerThread.Join();
        Console.WriteLine("main thread: Worker thread has terminated.");
    }
}

Aqui está a saída:

main thread: starting worker thread...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: terminating gracefully...
main thread: worker thread has terminated

Consulte também

Tarefas

Exemplo de Threading

Conceitos

Guia de Programação C#

Referência

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

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

Thread

volátil (translation from VPE for Csharp Reference)

Mutex

Monitor

Start

IsAlive

Sleep

Join

Abort

Outros recursos

Threads gerenciadas

Exemplos de Threading