Chamar APIs assíncronas no Visual Basic ou C#

A Plataforma Universal do Windows (UWP) inclui muitas APIs assíncronas para garantir que o seu aplicativo permaneça responsivo ao executar trabalhos demorados. Este tópico descreve como usar métodos assíncronos da UWP em C# ou Microsoft Visual Basic.

As APIs assíncronas impedem que seu aplicativo aguarde a conclusão de grandes operações antes de continuar a execução. Por exemplo, um aplicativo que baixa informações da Internet pode passar vários segundos aguardando a chegada das informações. Se você usar um método síncrono para recuperar as informações, o aplicativo será bloqueado até que o método retorne. O aplicativo não responde à interação do usuário e, como parece não responder, o usuário pode ficar frustrado. Ao fornecer APIs assíncronas, a UWP ajuda a garantir que seu aplicativo permaneça responsivo ao usuário quando estiver executando operações longas.

A maioria das APIs assíncronas na UWP não tem equivalentes síncronos, portanto, você precisa ter certeza de entender como usar as APIs assíncronas com C# ou Visual Basic em seu aplicativo UWP (Plataforma Universal do Windows). Aqui, mostramos como chamar APIs assíncronas da UWP.

Usando APIs assíncronas

Por convenção, os métodos assíncronos recebem nomes que terminam em "Async". Normalmente, você chama APIs assíncronas em resposta à ação de um usuário, como quando o usuário clica em um botão. Chamar um método assíncrono em um manipulador de eventos é uma das maneiras mais simples de usar APIs assíncronas. Aqui, usamos o operador await como exemplo.

Suponha que você tenha um aplicativo que lista os títulos das postagens do blog de um determinado local. O aplicativo possui um botão no qual o usuário clica para obter os títulos. Os títulos são exibidos em um TextBlock. Quando o usuário clica no botão, é importante que o aplicativo permaneça responsivo enquanto aguarda as informações do site do blog. Para garantir essa capacidade de resposta, a UWP fornece um método assíncrono, SyndicationClient.RetrieveFeedAsync, para baixar o feed.

O exemplo aqui obtém as listas de postagens de blog de um blog chamando o método assíncrono, SyndicationClient.RetrieveFeedAsync, e aguardando o resultado.

// Put the keyword async on the declaration of the event handler.
private async void Button_Click_1(object sender, RoutedEventArgs e)
{

    Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();

    Uri feedUri
        = new Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx");

    try
    {
        SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);

        // The rest of this method executes after await RetrieveFeedAsync completes.
        rssOutput.Text = feed.Title.Text + Environment.NewLine;

        foreach (SyndicationItem item in feed.Items)
        {
            rssOutput.Text += item.Title.Text + ", " +
                             item.PublishedDate.ToString() + Environment.NewLine;
        }
    }
    catch (Exception ex)
    {
        // Log Error.
        rssOutput.Text =
            "I'm sorry, but I couldn't load the page," +
            " possibly due to network problems." +
            "Here's the error message I received: "
            + ex.ToString();
    }
}
' Put the keyword Async on the declaration of the event handler.
Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
    Dim client As New Windows.Web.Syndication.SyndicationClient()
    Dim feedUri As New Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx")

    Try
        Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(feedUri)

        ' The rest of this method executes after the await operation completes.
        rssOutput.Text = feed.Title.Text & vbCrLf

        For Each item In feed.Items
            rssOutput.Text += $"{item.Title.Text}, {item.PublishedDate.ToString()}{vbCrLf}"
        Next

    Catch ex As Exception
        ' Log Error.
        rssOutput.Text = "I'm sorry, but I couldn't load the page," &
                         " possibly due to network problems." &
                         "Here's the error message I received: " &
                          ex.ToString()
    End Try

End Sub

Há algumas coisas importantes sobre este exemplo. Primeiro, a linha usa o operador await com a chamada para o método assíncrono, RetrieveFeedAsync. SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) Você pode pensar no operador await como informando ao compilador que você está chamando um método assíncrono, o que faz com que o compilador faça algum trabalho extra para que você não precise fazer isso. Em seguida, a declaração do manipulador de eventos inclui a palavra-chave async. Você deve incluir essa palavra-chave na declaração de método de qualquer método no qual você usa o operador await .

Neste tópico, não entraremos em muitos detalhes sobre o que o compilador faz com o operador await , mas vamos examinar o que seu aplicativo faz para que ele seja assíncrono e responsivo. Considere o que acontece quando você usa código síncrono. Por exemplo, suponha que haja um método chamado SyndicationClient.RetrieveFeed que é síncrono. (Não existe tal método, mas imagine que existe.) Se o aplicativo incluísse a linha SyndicationFeed feed = client.RetrieveFeed(feedUri), em vez de SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri), a execução do aplicativo seria interrompida até que o valor retornado de RetrieveFeed estivesse disponível. E enquanto seu aplicativo aguarda a conclusão do método, ele não pode responder a nenhum outro evento, como outro evento Click. Ou seja, seu aplicativo seria bloqueado até RetrieveFeed retornar.

Mas se você chamar client.RetrieveFeedAsync, o método inicia a recuperação e retorna imediatamente. Quando você usa await com RetrieveFeedAsync, o aplicativo sai temporariamente do manipulador de eventos. Em seguida, ele pode processar outros eventos enquanto RetrieveFeedAsync é executado de forma assíncrona. Isso mantém o aplicativo responsivo ao usuário. Quando RetrieveFeedAsync é concluído e o SyndicationFeed está disponível, o aplicativo essencialmente entra novamente no manipulador de eventos de onde parou, depois SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)de , e conclui o restante do método.

O bom de usar o operador await é que o código não parece muito diferente de como o código se parece se você usasse RetrieveFeed o método imaginário. Há maneiras de escrever código assíncrono em C# ou Visual Basic sem o operador await , mas o código resultante tende a enfatizar a mecânica de execução assíncrona. Isso torna o código assíncrono difícil de escrever, difícil de entender e difícil de manter. Usando o operador await , você obtém os benefícios de um aplicativo assíncrono sem tornar seu código complexo.

Tipos de retorno e resultados de APIs assíncronas

Se você seguiu o link para RetrieveFeedAsync, deve ter notado que o tipo de retorno de RetrieveFeedAsync não é um SyndicationFeed. Em vez disso, o tipo de retorno é IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>. Visualizada a partir da sintaxe bruta, uma API assíncrona retorna um objeto que contém o resultado dentro dela. Embora seja comum, e às vezes útil, pensar em um método assíncrono como sendo aguardável, o operador await realmente opera no valor retornado do método, não no método. Quando você aplica o operador await , o que você obtém de volta é o resultado de chamar GetResult no objeto retornado pelo método. No exemplo, o SyndicationFeed é o resultado de RetrieveFeedAsync.GetResult().

Ao usar um método assíncrono, você pode examinar a assinatura para ver o que receberá de volta depois de aguardar o valor retornado do método. Todas as APIs assíncronas na UWP retornam um dos seguintes tipos:

O tipo de resultado de um método assíncrono é o mesmo que o TResult parâmetro type. Tipos sem um TResult não têm um resultado. Você pode pensar no resultado como sendo nulo. No Visual Basic, um procedimento Sub é equivalente a um método com um tipo de retorno void.

A tabela aqui fornece exemplos de métodos assíncronos e lista o tipo de retorno e o tipo de resultado de cada um.

Método assíncrono Tipo de retorno Tipo de resultado
SyndicationClient.RetrieveFeedAsync IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> SyndicationFeed
FileOpenPicker.PickSingleFileAsync IAsyncOperation<StorageFile> StorageFile
XmlDocument.SaveToFileAsync IAsyncAction void
InkStrokeContainer.LoadAsync IAsyncActionWithProgress<UInt64> void
DataReader.LoadAsync DataReaderLoadOperation, uma classe de resultados personalizada que implementa IAsyncOperation<UInt32> UInt32

 

Os métodos assíncronos definidos no .NET para aplicativos UWP têm o tipo de retorno Task ou Task<TResult>. Os métodos que retornam Task são semelhantes aos métodos assíncronos na UWP que retornam IAsyncAction. Em cada caso, o resultado do método assíncrono é nulo. O tipo de retorno Task<TResult> é semelhante a IAsyncOperation<TResult>, pois o resultado do método assíncrono ao executar a tarefa é do mesmo tipo que o TResult parâmetro type. Para obter mais informações sobre como usar o .NET para aplicativos e tarefas UWP, consulte Visão geral dos aplicativos do .NET para Windows Runtime.

Tratar erros

Ao usar o operador await para recuperar seus resultados de um método assíncrono, você pode usar um bloco try/catch para lidar com erros que ocorrem em métodos assíncronos, assim como você faz para métodos síncronos. O exemplo anterior encapsula o método RetrieveFeedAsync e a operação await em um bloco try/catch para lidar com erros quando uma exceção é lançada.

Quando os métodos assíncronos chamam outros métodos assíncronos, qualquer método assíncrono que resulte em uma exceção será propagado para os métodos externos. Isso significa que você pode colocar um bloco try/catch no método mais externo para capturar erros para os métodos assíncronos aninhados. Novamente, isso é semelhante a como você captura exceções para métodos síncronos. No entanto, você não pode usar await no bloco catch .

Dica A partir do C# no Microsoft Visual Studio 2005, você pode usar await no bloco catch .

Resumo e próximas etapas

O padrão de chamar um método assíncrono que mostramos aqui é o mais simples de usar quando você chama APIs assíncronas em um manipulador de eventos. Você também pode usar esse padrão ao chamar um método assíncrono em um método substituído que retorna void ou Sub no Visual Basic.

Ao encontrar métodos assíncronos na UWP, é importante lembrar:

  • Por convenção, os métodos assíncronos recebem nomes que terminam em "Async".
  • Qualquer método que use o operador await deve ter sua declaração marcada com a palavra-chave async .
  • Quando um aplicativo encontra o operador await , o aplicativo permanece responsivo à interação do usuário enquanto o método assíncrono é executado.
  • Aguardando o valor retornado por um método assíncrono retorna um objeto que contém o resultado. Na maioria dos casos, o resultado contido no valor retornado é o que é útil, não o valor retornado em si. Você pode encontrar o tipo do valor contido no resultado examinando o tipo de retorno do método assíncrono.
  • O uso de APIs assíncronas e padrões assíncronos geralmente é uma maneira de melhorar a capacidade de resposta do seu aplicativo.

O exemplo neste tópico gera um texto semelhante a este.

Windows Experience Blog
PC Snapshot: Sony VAIO Y, 8/9/2011 10:26:56 AM -07:00
Tech Tuesday Live Twitter #Chat: Too Much Tech #win7tech, 8/8/2011 12:48:26 PM -07:00
Windows 7 themes: what’s new and what’s popular!, 8/4/2011 11:56:28 AM -07:00
PC Snapshot: Toshiba Satellite A665 3D, 8/2/2011 8:59:15 AM -07:00
Time for new school supplies? Find back-to-school deals on Windows 7 PCs and Office 2010, 8/1/2011 2:14:40 PM -07:00
Best PCs for blogging (or working) on the go, 8/1/2011 10:08:14 AM -07:00
Tech Tuesday – Blogging Tips and Tricks–#win7tech, 8/1/2011 9:35:54 AM -07:00
PC Snapshot: Lenovo IdeaPad U460, 7/29/2011 9:23:05 AM -07:00
GIVEAWAY: Survive BlogHer with a Sony VAIO SA and a Samsung Focus, 7/28/2011 7:27:14 AM -07:00
3 Ways to Stay Cool This Summer, 7/26/2011 4:58:23 PM -07:00
Getting RAW support in Photo Gallery & Windows 7 (…and a contest!), 7/26/2011 10:40:51 AM -07:00
Tech Tuesdays Live Twitter Chats: Photography Tips, Tricks and Essentials, 7/25/2011 12:33:06 PM -07:00
3 Tips to Go Green With Your PC, 7/22/2011 9:19:43 AM -07:00
How to: Buy a Green PC, 7/22/2011 9:13:22 AM -07:00
Windows 7 themes: the distinctive artwork of Cheng Ling, 7/20/2011 9:53:07 AM -07:00