Invocação de método assíncrono - Asynchronous method invocation

Na programação de computador multithread , a invocação de método assíncrono ( AMI ), também conhecida como chamadas de método assíncrono ou o padrão assíncrono é um padrão de design no qual o site da chamada não é bloqueado enquanto espera o código chamado terminar. Em vez disso, o thread de chamada é notificado quando a resposta chega. Buscar uma resposta é uma opção indesejada.

fundo

AMI é um padrão de design para invocação assíncrona de métodos potencialmente de longa duração de um objeto . É equivalente ao padrão IOU ("eu devo a você") descrito em 1996 por Allan Vermeulen.

Na maioria das linguagens de programação, um método chamado é executado de forma síncrona, ou seja, no thread de execução a partir do qual é invocado. Se o método levar muito tempo para ser concluído, por exemplo, porque está carregando dados pela Internet, o thread de chamada será bloqueado até que o método seja concluído. Quando isso não for desejado, é possível iniciar um "thread de trabalho" e invocar o método a partir daí. Na maioria dos ambientes de programação, isso requer muitas linhas de código, especialmente se for tomado cuidado para evitar a sobrecarga que pode ser causada pela criação de muitos threads. A AMI resolve esse problema porque aumenta um método de objeto potencialmente de longa duração ("síncrono") com uma variante "assíncrona" que retorna imediatamente, junto com métodos adicionais que facilitam o recebimento de notificação de conclusão ou a espera pela conclusão em mais tarde.

Um uso comum de AMI é no padrão de design de objeto ativo . As alternativas são a chamada de método síncrona e objetos futuros . Um exemplo de aplicativo que pode fazer uso do AMI é um navegador da web que precisa exibir uma página da web antes mesmo de todas as imagens serem carregadas.

Como o método é um caso especial de procedimento , a invocação de método assíncrono é um caso especial de chamada de procedimento assíncrono .

Implementações

Classe Java

A classe FutureTask em Java usa eventos para resolver o mesmo problema. Esse padrão é uma variante da AMI cuja implementação carrega mais sobrecarga, mas é útil para objetos que representam componentes de software .

.NET Framework

  • Padrão de modelo de programação assíncrona (APM) (usado antes do .NET Framework 2.0)
  • Padrão assíncrono baseado em eventos (EAP) (usado no .NET Framework 2.0)
  • Padrão assíncrono baseado em tarefas (TAP) (usado no .NET Framework 4.0)

Exemplo

O exemplo a seguir é vagamente baseado em um estilo AMI padrão usado no .NET Framework . Dado um método Accomplish , adiciona-se dois novos métodos BeginAccomplish e EndAccomplish :

class Example 
{
    Result       Accomplish(args )
    IAsyncResult BeginAccomplish(args )
    Result       EndAccomplish(IAsyncResult a)
    
}

Ao chamar BeginAccomplish , o cliente recebe imediatamente um objeto do tipo AsyncResult (que implementa a IAsyncResult interface), para que possa continuar o thread de chamada com trabalho não relacionado. No caso mais simples, eventualmente não existe mais tal trabalho, e o cliente chama EndAccomplish (passando o objeto recebido anteriormente), que bloqueia até que o método seja concluído e o resultado esteja disponível. O AsyncResult objeto normalmente fornece pelo menos um método que permite ao cliente consultar se o método de longa duração já foi concluído:

interface IAsyncResult 
{
    bool HasCompleted()
    
}

Também é possível passar um método de retorno de chamada para BeginAccomplish , para ser invocado quando o método de longa execução for concluído. Normalmente, ele chama EndAccomplish para obter o valor de retorno do método de longa duração. Um problema com o mecanismo de retorno de chamada é que a função de retorno de chamada é executada naturalmente no thread de trabalho (em vez de no thread de chamada original), o que pode causar condições de corrida.

Na documentação do .NET Framework, o termo padrão assíncrono baseado em evento se refere a um estilo alternativo de API (disponível desde .NET 2.0) usando um método chamado em AccomplishAsync vez de BeginAccomplish . Uma diferença superficial é que, neste estilo, o valor de retorno do método de longa duração é passado diretamente para o método de retorno de chamada. Muito mais importante, a API usa um mecanismo especial para executar o método de retorno de chamada (que reside em um objeto de evento do tipo AccomplishCompleted ) no mesmo encadeamento em que BeginAccomplish foi chamado. Isso elimina o perigo de condições de corrida, tornando a API mais fácil de usar e adequada para componentes de software; por outro lado, essa implementação do padrão vem com sobrecarga adicional de criação e sincronização de objetos.

Referências

  1. ^ "Invocação de método assíncrono" . Programação Distribuída com Gelo . ZeroC, Inc. Arquivado do original em 5 de janeiro de 2008 . Página visitada em 22 de novembro de 2008 .
  2. ^ Vermeulen, Allan (junho de 1996). "An Asynchronous Design Pattern" . Diário do Dr. Dobb . Página visitada em 22 de novembro de 2008 .
  3. ^ Nash, Trey (2007). "Encadeamento em C #". C # 2008 acelerado . Apress. ISBN   978-1-59059-873-3 .
  4. ^ Lavender, R. Greg; Douglas C. Schmidt . "Objeto ativo" (PDF) . Arquivado do original (PDF) em 24/09/2012 . Página visitada em 22 de novembro de 2008 . Citar diário requer |journal= ( ajuda )
  5. ^ "Classe FutureTask" . Oráculo. 2011. Arquivado do original em 25/06/2013 . Retirado 2015-06-29 .
  6. ^ "Modelo de programação assíncrona" . Microsoft. 2015 . Retirado 2015-06-29 .
  7. ^ "Visão geral do padrão assíncrono baseado em eventos" . Microsoft. 2015 . Retirado 2015-06-29 .
  8. ^ "Padrão assíncrono baseado em tarefas" . Microsoft. 2015 . Retirado 2015-06-29 .
  9. ^ "Padrões de projeto de programação assíncrona" . Guia do desenvolvedor do .NET Framework . Microsoft Developer Network. Arquivado do original em 22 de novembro de 2008 . Página visitada em 22 de novembro de 2008 .
  10. ^ "Visão geral da programação assíncrona" . Guia do desenvolvedor do .NET Framework . Microsoft Developer Network. Arquivado do original em 7 de dezembro de 2008 . Página visitada em 22 de novembro de 2008 .
  11. ^ "Usando um delegado AsyncCallback para encerrar uma operação assíncrona" . Guia do desenvolvedor do .NET Framework . Microsoft Developer Network. Arquivado do original em 23 de dezembro de 2008 . Página visitada em 22 de novembro de 2008 .
  12. ^ "Problemas de simultaneidade" . Programação Distribuída com Gelo . ZeroC, Inc. Arquivado do original em 28 de março de 2008 . Página visitada em 22 de novembro de 2008 .
  13. ^ Christian Nagel; Bill Evjen; Jay Glynn; Karli Watson e Morgan Skinner (2008). "Padrão assíncrono baseado em eventos". Professional C # 2008 . Wiley. pp.  570 -571. ISBN   9780470191378 .
  14. ^ "Programação multithread com o padrão assíncrono baseado em eventos" . Guia do desenvolvedor do .NET Framework . Microsoft Developer Network. Arquivado do original em 25 de dezembro de 2008 . Página visitada em 22 de novembro de 2008 .
  15. ^ "Decidindo quando implementar o padrão assíncrono baseado em eventos" . Guia do desenvolvedor do .NET Framework . Microsoft Developer Network. Arquivado do original em 22 de novembro de 2008 . Página visitada em 22 de novembro de 2008 .

Leitura adicional