Compartilhar via


padrão assíncrono baseado em evento Visão geral sobre

Aplicativos que realizar várias tarefas simultaneamente, embora permaneçam responsivo a interação do usuário, geralmente exigem um design que usa vários threads.The System.Threading espaço para nome fornece todas as ferramentas necessárias para criar aplicativos multithread de alto desempenho, mas efetivamente o uso dessas ferramentas requer experiência significativa com multithread engenharia de software. Para aplicativos multithread relativamente simples, a BackgroundWorker componente fornece uma solução simples. Para aplicativos assíncronos mais sofisticados, considere implementar uma classe que estejam de acordo com o padrão assíncrono baseado em evento.

O padrão assíncrono baseado em eventoo disponibiliza as vantagens de aplicativos de vários segmentos enquanto oculta muitas das questões complexas inerentes ao design multithread.Usando uma classe que oferece suporte a esse padrão pode permitir que você:

  • Executar tarefas demoradas, sistema autônomo downloads e sistema autônomo operações de banco de dados "em"segundo plano, sem interromper o seu aplicativo.

  • executar várias operações simultaneamente, receber notificações quando cada um é concluída.

  • Aguardar recursos se torne disponível sem parar ("deslocadas") do aplicativo.

  • Se comunicar com operações assíncrono usando o modelo de eventos e delegados familiar pendentes.Para obter mais informações sobre como usar evento manipuladores e delegados, consulte Eventos e representantes.

Uma classe que oferece suporte a padrão assíncrono baseado em eventoo serão um ou mais métodos nomeou MethodNameAsync.Esses métodos podem espelhar versões síncronas, qual efetuar a mesma operação no thread corrente.A classe também pode ter um MethodNameCompleted evento e ele podem ter um MethodNameAsyncCancel (ou simplesmente CancelAsync) método.

PictureBox é um componente comum que suporta o padrão assíncrono com base em eventos. Você pode baixar uma imagem sincronicamente, chamando seu Loadmétodo, mas se a imagem for grande ou se a conexão de rede estiver lenta, seu aplicativo irá parar ("travar") até que a operação de download seja concluída e a telefonar para Load Retorna.

Se você quiser que o aplicativo manter em execução enquanto a imagem está carregando, poderá telefonar o LoadAsync método e o identificador do LoadCompleted evento, sistema autônomo você trataria de qualquer Outros evento. Quando você liga o LoadAsyncmétodo, o aplicativo continuará a ser executado enquanto o baixar continua em um thread separado ("no plano de fundo"). Seu evento manipulador será chamado quando a operação de carregamento de imagem estiver concluída e seu evento manipulador pode examinar o AsyncCompletedEventArgs parâmetro para determinar se o baixar foi concluído com êxito.

O padrão assíncrono baseado em eventoo requer que uma operação assíncrona pode ser cancelada e o PictureBox controle oferece suporte a esse requisito com sua CancelAsync método. De chamadaCancelAsync envia uma solicitação para parar o baixar pendente, e quando a tarefa for cancelada, o LoadCompleted evento é gerado.

Cuidado:

É possível que o baixar será Concluir assim sistema autônomo o CancelAsync solicitação é feita, isso Cancelled pode não refletir a solicitação para cancelar. Isso é chamado um condição de corrida e é um problema comum de programação multissegmentada.Para obter mais informações sobre problemas no programação multissegmentada, consulte Gerenciado Threading práticas recomendadas .

Características do padrão assíncrono baseado em evento

O padrão assíncrono baseado em evento pode tomar vários formulários, dependendo da complexidade das operações suportadas por uma determinada classe.As classes mais simples podem ter um único método MethodNameAsync e um evento correspondente MethodNameCompleted.Classes mais complexas podem ter vários métodos MethodNameAsync, cada um com um evento correspondente MethodNameCompleted, bem como versões síncronas desses métodos.Classes podem opcionalmente suportar cancelamento, relatórios de progresso, e resultados incrementais para cada método assíncrono.

Um método assíncrono também pode oferecer suporte a várias chamadas pendentes (várias chamadas simultâneas), permitindo a seu código chamá-las qualquer número de vezes antes que ele conclua outras operações pendentes.Corretamente tratamento essa situação pode exigir de seu aplicativo controlar a conclusão de cada operação.

Exemplos do padrão assíncrono baseado em evento

The SoundPlayer e PictureBox componentes implementações simples representam o padrão assíncrono baseado em evento. The WebClient e BackgroundWorker componentes implementações mais complexas de representam o padrão assíncrono baseado em eventoo.

A seguir é uma declaração de classe de exemplo que esteja de acordo com o padrão:

Public Class AsyncExample
    ' Synchronous methods.
    Public Function Method1(ByVal param As String) As Integer 
    Public Sub Method2(ByVal param As Double) 

    ' Asynchronous methods.
    Overloads Public Sub Method1Async(ByVal param As String) 
    Overloads Public Sub Method1Async(ByVal param As String, ByVal userState As Object) 
    Public Event Method1Completed As Method1CompletedEventHandler

    Overloads Public Sub Method2Async(ByVal param As Double) 
    Overloads Public Sub Method2Async(ByVal param As Double, ByVal userState As Object) 
    Public Event Method2Completed As Method2CompletedEventHandler

    Public Sub CancelAsync(ByVal userState As Object) 

    Public ReadOnly Property IsBusy () As Boolean

    ' Class implementation not shown.
End Class
public class AsyncExample
{
    // Synchronous methods.
    public int Method1(string param);
    public void Method2(double param);

    // Asynchronous methods.
    public void Method1Async(string param);
    public void Method1Async(string param, object userState);
    public event Method1CompletedEventHandler Method1Completed;

    public void Method2Async(double param);
    public void Method2Async(double param, object userState);
    public event Method2CompletedEventHandler Method2Completed;

    public void CancelAsync(object userState);

    public bool IsBusy { get; }

    // Class implementation not shown.
}

O fictíciaAsyncExample classe possui dois métodos, de qual suporte síncrono e um síncrono invocações. Sobrecargas de síncronas funcionem como qualquer método chamar e executar a operação no thread de telefonar; se a operação for time-consumindo, pode haver um notável atraso antes do retorno da telefonar.Sobrecargas de assíncrono começa a operação em outro thread e retornam imediatamente, permitindo que o thread de chamada continuar enquanto executa a operação "em segundo plano."

Overloads de método assíncrono

Há potencialmente duas sobrecargas para operações assíncrono: invocação de único e múltiplo invocação.Você pode distinguir nessas duas formas por suas assinaturas de método: o formulário de várias invocação tem um parâmetro extra chamado userState. Este formulário possibilita que seu código para chamar Method1Async(string param, object userState) várias vezes sem aguardar pendentes operações assíncrono para terminar. Se, por Outros lado, você tentar chamar Method1Async(string param) antes de uma telefonar anterior foi concluída, o método indica uma InvalidOperationException.

The userState parâmetro de sobrecargas de invocação de vários permite distinguir entre as operações assíncrono. Você fornecer um valor exclusivo (por exemplo, um código GUID ou hash) para cada telefonar para Method1Async(string param, object userState), e quando cada operação é concluída, o manipulador de eventos pode determinar qual instância da operação disparou o evento de conclusão.

Pendente operações de acompanhamento

Se você usar sobrecargas de invocação de múltiplos, seu código precisará manter controle sobre o userState objetos (identificações de tarefa) para tarefas pendentes. Cada telefonar para Method1Async(string param, object userState), você normalmente irá gerar um novo e exclusivo userState objeto e adicione-o a uma coleção. Quando a tarefa correspondente a este userState objeto dispara o evento de conclusão, examinará sua implementação de método de conclusão AsyncCompletedEventArgs.UserState e removê-lo da sua coleção. Usado dessa forma, a userState parâmetro usa a função de um identificação da tarefa.

Observação:

Você deve ter cuidado para fornecer um valor exclusivo para userState em suas chamadas a invocação de várias sobrecargas. Identificações de tarefas não-exclusivo causará throw classe assíncrono um ArgumentException.

Cancelamento pendente operações

É importante ser capaz de cancelar operações assíncrono a qualquer momento antes de sua conclusão.Classes que implementam o padrão assíncrono evento-based terá um CancelAsync método (se existirem vários métodos assíncronos) ou um MethodNameAsyncCancel método (se houver apenas um método assíncrono).

Métodos que permitem que várias chamadas levar um userState parâmetro pode ser usado para controlar o tempo de vida de cada tarefa. CancelAsync leva uma userState parâmetro, que permite que você cancele determinado tarefas pendentes.

Métodos que oferecem suporte a apenas uma única operação ao mesmo time, como pendenteMethod1Async(string param), não são cancelável.

Recebendo atualizações de andamento e resultados incrementais

Uma classe que segue o padrão assíncrono com base em eventos pode fornecer, opcionalmente, um evento para controlar o andamento e resultados incrementais.Isso geralmente irá ser nomeado ProgressChanged ou MethodNameProgressChangede seu manipulador de eventos correspondente levará um ProgressChangedEventArgs parâmetro.

The event handler for the ProgressChangedevent can examine the ProgressChangedEventArgs.ProgressPercentage property to determine what percentage of an asynchronous task has been completed.Essa propriedade irá variar de 0 a 100 e podem ser usado para atualizar o Value propriedade de um ProgressBar. Se várias operações assíncrono estão pendentes, você pode usar o ProgressChangedEventArgs.UserState propriedade distinguir qual operação relatar o andamento.

Algumas classes podem relatar resultados incrementais sistema autônomo continuar sistema autônomo operações assíncrono.Esses resultados serão armazenados em uma classe que deriva de ProgressChangedEventArgs e eles aparecerão sistema autônomo propriedades na classe derivada. Você pode acessar esses resultados no manipulador de eventos para o ProgressChanged evento, exatamente sistema autônomo você acessaria o ProgressPercentage propriedade. Se várias operações assíncrono estão pendentes, você pode usar o UserState propriedade distinguir qual operação está relatando resultados incrementais.

Consulte também

Tarefas

Como: Use os componentes que suportam o padrão assíncrono baseado em evento

Como: Executar uma operação no plano de fundo

Como: Implementar um formulário que usa uma operação de plano de fundo

Conceitos

Práticas recomendadas para implementar o padrão assíncrono com base em eventos

Decidindo quando implementar o padrão assíncrono com base em eventos

Referência

ProgressChangedEventArgs

BackgroundWorker

AsyncCompletedEventArgs

Outros recursos

Vários segmentos de programação com o padrão assíncrono baseado em eventoo