Decidindo quando implementar o padrão assíncrono baseado em evento

O Padrão assíncrono baseado em evento oferece um padrão para expor o comportamento assíncrono de uma classe. Com a introdução desse padrão, o .NET define dois padrões para expor o comportamento assíncrono: o padrão assíncrono baseado na System.IAsyncResult interface e o padrão baseado em eventos. Este artigo descreve quando é apropriado implementar ambos os padrões.

Para obter mais informações sobre a programação assíncrona com a interface IAsyncResult, confira APM (modelo de programação assíncrona).

Noções básicas gerais

Em geral, você deve expor recursos assíncronos usando o Padrão assíncrono baseado em evento sempre que possível. No entanto, há alguns requisitos que o padrão baseado em evento não pode atender. Nesses casos, talvez seja necessário implementar o padrão IAsyncResult além do padrão baseado em evento.

Observação

É raro o padrão IAsyncResult ser implementado sem que o padrão baseado em evento também seja implementado.

Diretrizes

A lista a seguir descreve as diretrizes para quando você deve implementar o Padrão Assíncrono baseado em Evento:

  • Use o padrão baseado em evento como a API padrão para expor o comportamento assíncrono para sua classe.

  • Não exponha o padrão IAsyncResult, principalmente quando a classe for usada em um aplicativo cliente, por exemplo, o Windows Forms.

  • Basta expor o padrão IAsyncResult quando ele for necessário para atender seus requisitos. Por exemplo, a compatibilidade com uma API existente pode exigir que você exponha o padrão IAsyncResult.

  • Não exponha o padrão IAsyncResult sem também expor o padrão baseado em evento.

  • Se você precisar expor o padrão IAsyncResult, exponha-o como uma opção avançada. Por exemplo, se você gerar um objeto de proxy, gere o padrão baseado em evento por padrão, com uma opção para gerar o padrão IAsyncResult.

  • Crie sua implementação do padrão baseado em evento na implementação do padrão IAsyncResult.

  • Evitar expor os dois padrões, o padrão baseado em evento e o padrão IAsyncResult, na mesma classe. Exponha o padrão baseado em evento em classes de "nível superior" e o padrão IAsyncResult em classes de "nível inferior". Por exemplo, compare o padrão baseado em evento no componente WebClient com o padrão IAsyncResult na classe HttpRequest.

    • Exponha o padrão baseado em evento e o padrão IAsyncResult na mesma classe quando a compatibilidade exigir isso. Por exemplo, se já tiver lançado uma API que usa o padrão IAsyncResult, precisará manter o padrão IAsyncResult por questões de compatibilidade com versões anteriores.

    • Exponha o padrão baseado em evento e o padrão IAsyncResult na mesma classe se a complexidade do modelo de objeto resultante for maior que o benefício de separar as implementações. É melhor expor os dois padrões em uma única classe para evitar expor o padrão baseado em evento.

    • Se quiser expor o padrão baseado em evento e o padrão IAsyncResult em uma única classe, use o EditorBrowsableAttribute definido como Advanced para marcar a implementação do padrão IAsyncResult como um recurso avançado. Isso dá a indicação aos ambientes de design, como o Visual Studio IntelliSense, para não exibir as propriedades e os métodos de IAsyncResult. Essas propriedades e métodos ainda são totalmente utilizáveis, mas, trabalhando com o IntelliSense, o desenvolvedor terá uma visão clara da API.

Critérios para expor o Padrão de IAsyncResult além do Padrão baseado em evento

O Padrão Assíncrono Baseado em Evento é muito vantajoso quando aplicado aos cenários mencionados anteriormente. No entanto, ele apresenta algumas desvantagens e você precisa estar atento caso o desempenho for seu requisito mais importante.

Há três cenários que o padrão baseado em evento não trata e o padrão IAsyncResult também não:

Você pode lidar com esses cenários usando o padrão baseado em evento, mas isso é mais complicado do que usar o padrão IAsyncResult.

Os desenvolvedores geralmente usam o padrão IAsyncResult em serviços que normalmente têm requisitos de desempenho muito elevados. Por exemplo, a sondagem do cenário de conclusão é uma técnica de servidor de alto desempenho.

Além disso, o padrão baseado em evento é menos eficiente que o padrão IAsyncResult porque cria mais objetos, especialmente o EventArgs, e por sincronizar entre threads.

A lista a seguir mostra algumas recomendações a serem seguidas se você decidir usar o padrão IAsyncResult:

  • Só exponha o padrão IAsyncResult quando você precisar de suporte para os objetos WaitHandle ou IAsyncResult.

  • Só exponha o padrão IAsyncResult quando você tiver uma API existente que usa o padrão IAsyncResult.

  • Se você já tiver uma API baseada no padrão IAsyncResult, considere também expor o padrão baseado em evento em sua próxima versão.

  • Só exponha o padrão IAsyncResult caso tiver requisitos de alto desempenho que você verificou não poderem ser atendidos pelo padrão baseado em evento, mas que podem ser atendidos pelo padrão IAsyncResult.

Confira também