Modelo de programação assíncrona (APM)

Uma operação assíncrona que utiliza o padrão de design IAsyncResult é implementada como dois métodos chamados BeginOperationName e EndOperationName que começam e terminam a operação assíncrona OperationName, respectivamente. Por exemplo, a classe FileStream fornece os métodos BeginRead e EndRead para ler os bytes de um arquivo de forma assíncrona. Esses métodos implementam a versão assíncrona do método Read.

Observação

A partir do .NET Framework 4, a Biblioteca de Paralelismo de Tarefas fornece um novo modelo de programação paralela e assíncrona. Para saber mais, confira Biblioteca de Paralelismo de Tarefas (TPL) e Padrão Assíncrono Baseado em Tarefa (TAP).

Depois de chamar BeginOperationName, um aplicativo pode continuar a executar as instruções no thread de chamada, enquanto a operação assíncrona ocorre em um thread diferente. Cada chamada para BeginOperationName, o aplicativo também deve chamar EndOperationName para obter os resultados da operação.

Começando uma operação assíncrona

O método BeginOperationName inicia a operação assíncrona OperationName e retorna um objeto que implementa a interface IAsyncResult. Os objetos IAsyncResult armazenam as informações sobre uma operação assíncrona. A tabela a seguir mostra informações sobre uma operação assíncrona.

Membro DESCRIÇÃO
AsyncState Um objeto específico do aplicativo opcional que contém informações sobre a operação assíncrona.
AsyncWaitHandle Um WaitHandle que pode ser usado para bloquear a execução do aplicativo até que a operação assíncrona seja concluída.
CompletedSynchronously Um valor que indica se a operação assíncrona foi concluída no thread usado para chamar BeginOperationName em vez de concluir em um thread ThreadPool separado.
IsCompleted Um valor que indica se a operação assíncrona foi concluída.

Um método BeginOperationName usa qualquer parâmetro declarado na assinatura da versão síncrona do método que é passado por valor ou referência. Os parâmetros de saída não são parte da assinatura do método BeginOperationName. A assinatura do método BeginOperationName também inclui dois parâmetros adicionais. O primeiro deles define um delegado AsyncCallback que faz referência a um método que é chamado quando a operação assíncrona é concluída. O chamador pode especificar null (Nothing no Visual Basic) se não desejar um método chamado quando a operação for concluída. O segundo parâmetro adicional é um objeto definido pelo usuário. Esse objeto pode ser usado para passar informações de estado específico do aplicativo para o método invocado quando a operação assíncrona é concluída. Se um método BeginOperationName usar parâmetros adicionais específicos da operação, como uma matriz de bytes para armazenar os bytes lidos de um arquivo, o AsyncCallback e o objeto de estado do aplicativo serão os últimos parâmetros da assinatura de método BeginOperationName.

BeginOperationName retorna o controle para o thread de chamada imediatamente. Se o método BeginOperationName gerar exceções, as exceções serão geradas antes de a operação assíncrona ser iniciada. Se o método BeginOperationName gerar exceções, o método de retorno de chamada não será invocado.

Encerrando uma operação assíncrona

O método EndOperationName termina a operação assíncrona OperationName. O valor retornado do método EndOperationName é do mesmo tipo retornado pela sua contraparte síncrona e é específico para a operação assíncrona. Por exemplo, o método EndRead retorna o número de bytes lidos de um FileStream e o método EndGetHostByName retorna um objeto IPHostEntry que contém informações sobre um computador host. O método EndOperationName usa qualquer parâmetro declarado de referência na assinatura da versão síncrona do método. Além dos parâmetros do método síncrono, o método EndOperationName também inclui um parâmetro IAsyncResult. Os chamadores devem passar a instância retornada pela chamada correspondente para BeginOperationName.

Se a operação assíncrona representada pelo objeto IAsyncResult não tiver sido concluída quando EndOperationName for chamado, EndOperationName bloqueará o thread de chamada até que a operação assíncrona seja concluída. As exceções geradas pela operação assíncrona são geradas do método EndOperationName. O efeito da chamada para o método EndOperationName várias vezes com o mesmo IAsyncResult não é definido. Da mesma forma, chamar o método EndOperationName com um IAsyncResult que não foi retornado pelo método Begin relacionado também não será definido.

Observação

Para qualquer um dos cenários indefinidos, os implementadores devem considerar a geração de InvalidOperationException.

Observação

Os implementadores deste padrão de design devem notificar o chamador de que a operação assíncrona está concluída, definindo IsCompleted como true, chamando o método de retorno de chamada assíncrono (se tiver sido especificado) e sinalizando o AsyncWaitHandle.

Os desenvolvedores de aplicativos tem várias opções de design para acessar os resultados da operação assíncrona. A opção correta depende se o aplicativo tem instruções que podem ser executadas enquanto a operação é concluída. Se um aplicativo não puder executar trabalho adicional até que ele receba os resultados da operação assíncrona, o aplicativo deverá ser bloqueado até que os resultados estejam disponíveis. Para bloquear até que uma operação assíncrona seja concluída, você poderá usar uma das seguintes abordagens:

Os aplicativos que não precisarem ser bloqueados enquanto a operação assíncrona é concluída podem usar uma das seguintes abordagens:

Confira também