Compartilhar via


Aplicativos multithread (C# e Visual Basic)

Com Visual Basic e C#, você pode gravar aplicativos que executam várias tarefas ao mesmo tempo. Tarefas com o potencial de manter outras tarefas podem executar em segmentos separados, um processo conhecido como multithreading ou livre segmentação .

Aplicativos que usam multithreading são mais responsivo para entrada do usuário, pois o interface do usuário permanece ativo como processador-intenso tarefas Executar em separam segmentos. Multithreading também é útil quando você cria aplicativos escalonáveis, porque você pode adicionar segmentos à medida que aumenta a carga de trabalho.

ObservaçãoObservação

Visual Studio 2010e .NET Framework 4 aperfeiçoam o suporte a programação paralela, fornecendo um novo tempo de execução, novos tipos de biblioteca de classe e novas ferramentas de diagnóstico. Para obter mais informações, consulte Programação em paralela a.NET Framework.

Usando o Componente BackgroundWorker

A maneira mais confiável de se criar um aplicativo com vários segmentos é usar o componente BackgroundWorker. Essa classe gerencia um segmento separado dedicado a processar o método que você especificar. Para um exemplo, consulte Demonstra Passo a passo: Multithreading com o componente BackgroundWorker (C# e Visual Basic).

Para iniciar uma operação em segundo plano, crie um BackgroundWorker e espere eventos que informem o andamento da operação e sinalizam quando a operação é concluída. Você pode criar o objeto BackgroundWorker programaticamente, ou você pode arrastá-lo para um formulário na guia Componentes da Caixa de Ferramentas . Se você criar o BackgroundWorker na caixa Designer de Formulários , ele aparece na Bandeja do Componente , e suas propriedades são exibidas na janela de Propriedades.

Configurando uma Operação de Plano de Fundo

Para configurar para uma operação de plano de fundo, adicione um manipulador de eventos para o evento DoWork. Chame sua operação demorada neste manipulador de eventos.

Para iniciar a operação, chame RunWorkerAsync. Para receber notificações de atualizações de andamento, manipule o evento ProgressChanged. Para receber uma notificação quando a operação for concluída, manipule o evento RunWorkerCompleted.

Os métodos que manipulam os eventos ProgressChanged e RunWorkerCompleted podem acessar a interface do usuário do aplicativo, pois esses eventos são gerados no segmento que chamou o método RunWorkerAsync. No entanto, o manipulador de eventos DoWork não é pode trabalhar com qualquer objeto da interface do usuário porque ele é executado no segmento de plano de fundo.

Criando e Usando Threads

Se você precisar ter mais controle sobre o comportamento de segmentos do aplicativo, você pode gerenciar os segmentos você mesmo. No entanto, perceba que escrever os aplicativos multithread corretos pode ser difícil: Seu aplicativo pode parar de responder ou enfrentar erros transitórios causados por condições de corrida. Para obter mais informações, consulte Componentes de thread-Safe..

Criar um novo thread, declarando uma variável do tipo Thread e chamar o construtor, fornecendo o nome do procedimento ou método que você deseja executar no novo segmento. O código a seguir fornece um exemplo.

Dim newThread As New System.Threading.Thread(AddressOf AMethod)
System.Threading.Thread newThread =
    new System.Threading.Thread(AMethod);

Iniciando e Parando Segmentos

Para iniciar a execução de um novo thread, use o Start método, conforme mostrado no código a seguir.

newThread.Start()
newThread.Start();

Para parar a execução de um segmento, use o Abort método, conforme mostrado no código a seguir.

newThread.Abort()
newThread.Abort();

Além de iniciar e parar de threads, você também pode pausar segmentos chamando o Sleep ou Suspend método, retomar um thread suspenso, usando o Resume método e destruir um segmento usando o Abort método

Métodos de Threads

A tabela a seguir mostra alguns dos métodos que você pode usar para controlar segmentos individuais.

Método

Ação

Start

Faz com que um segmento comece a executar.

Sleep

Pausa um segmento por um período especificado.

Suspend

Pausa um segmento quando ele atinge um ponto de segurança.

Abort

Para um segmento quando ele atinge um ponto de segurança.

Resume

Reinicia um segmento suspenso

Join

Faz com que o segmento atual aguarde outro segmento para. Se usado com um valor de tempo limite, este método retornará True se o segmento termina no tempo alocado.

Pontos Seguros

A maioria desses métodos são autoexplicativos, mas o conceito de pontos seguros pode ser novidade para você. Pontos de segurança são locais no código onde é seguro para o Common Language Runtime executar coleta de lixo automática, o processo de liberação de variáveis não utilizadas e recuperação de memória. Quando você chamar o método Abort ou Suspend de um segmento, o Common Language Runtime analisa o código e determina um local apropriado para o segmento parar de executar.

Propriedades de Segmento

Segmentos também contêm diversas propriedades úteis, como mostrado na tabela a seguir:

Propriedade

Valor

IsAlive

Contém o valor True se um segmento estiver ativo.

IsBackground

Obtém ou define um valor booleano que indica se um segmento é ou deve ser um segmento de plano de fundo. Segmentos de plano de fundo são como segmentos de primeiro plano, mas um segmento de plano de fundo não impede que um processo pare. Depois que todos os segmentos de primeiro plano que pertencem a um processo tiverem interrompido, o Common Language Runtime finaliza o processo chamando o método Abort nos segmentos de plano de fundo que estão ainda ativos.

Name

Obtém ou define o nome de um segmento. Usados com mais frequência para descobrir segmentos individuais quando você depura.

Priority

Obtém ou define um valor que é usado pelo sistema operacional para priorizar agendamento de segmento.

ApartmentState

Obtém ou define o modelo de segmentação usado para um determinado segmento. Modelos de segmentação são importantes quando um segmento chama código não gerenciado.

ThreadState

Contém um valor que descreve um estado ou estados do segmento.

Prioridades de Segmento

Cada segmento possui uma propriedade de prioridade que determina o quão grande ou pequeno uma fatia de tempo do processador ele tem para executar. O sistema operacional aloca frações de tempo maiores para segmentos de alta prioridade e frações de tempo mais curtas para segmentos de baixa prioridade. Novos segmentos são criados com o valor de Normal, mas você pode alterar a propriedade Priority para qualquer valor na enumeração ThreadPriority.

Consulte ThreadPriority para obter uma descrição detalhada sobre as várias prioridades de segmento.

Segmentos de Primeiro Plano e Plano de Fundo

Um segmento de primeiro plano executa indefinidamente, enquanto um segmento de plano de fundo para, assim que o último segmento do primeiro plano foi interrompido. Você pode utilizar a propriedade IsBackground para determinar ou alterar o status do plano de fundo de um segmento.

Multithreading com Formulários e Controles

Enquanto multithreading se adequa melhor a executar procedimentos e métodos de classe, você também pode usá-lo com formulários e controles. Se você fizer isso, estaja ciente dos seguintes pontos:

  • Sempre que possível, execute métodos de um controle apenas no fio no qual ele foi criado. Se você precisar chamar um método de um controle de outro segmento, você deve usar Invoke para chamar o método.

  • Não use o SyncLock (Visual Basic) ou lock (C#) a instrução para threads de bloqueio que manipulam os controles ou formulários. Devido ao fato de que os métodos de controles e formulários às vezes chamam de volta um procedimento de chamada, você pode acabar inadvertidamente num impasse—uma situação na qual dois fios aguardam um ao outro para liberar a fechadura, fazendo com que o aplicativo seja interrompido.

Consulte também

Referência

Segmento de sincronização (C# e Visual Basic)

Invoke

InvokeRequired

Thread

Conceitos

Parâmetros e valores de retorno for Multithreaded Procedures (C# e Visual Basic)

Outros recursos

Multithreading em componentes

COMO: Criar um segmento usando Visual C#