Chamar APIs assíncronas no Visual Basic ou C#Call asynchronous APIs in C# or Visual Basic

A Plataforma Universal do Windows (UWP) inclui muitas APIs assíncronas para garantir que o seu aplicativo permaneça responsivo ao executar trabalhos demorados.The Universal Windows Platform (UWP) includes many asynchronous APIs to ensure that your app remains responsive when it does work that might take an extended amount of time. Este tópico descreve como usar métodos assíncronos da UWP em C# ou Microsoft Visual Basic.This topic discusses how to use asynchronous methods from the UWP in C# or Microsoft Visual Basic.

As APIs assíncronas evitam que o aplicativo aguarde a conclusão de operações grandes antes de continuar a execução.Asynchronous APIs keep your app from waiting for large operations to complete before continuing execution. Por exemplo, um aplicativo que baixa informações da Internet pode passar diversos segundos aguardando a chegada das informações.For example, an app that downloads info from the Internet might spend several seconds waiting for the info to arrive. Se você usar um método síncrono para recuperar as informações, o aplicativo ficará bloqueado até que o método seja retornado.If you use a synchronous method to retrieve the info, the app is blocked until the method returns. O aplicativo não responderá à interação do usuário e, como ele parecerá não responsivo, o usuário poderá ficar frustrado.The app won't respond to user interaction and because it seems non-responsive, the user might become frustrated. 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.By providing asynchronous APIs, the UWP helps to ensure that your app stays responsive to the user when it's performing long operations.

A maioria das APIs assíncronas da UWP não possui equivalentes síncronos, por isso você tem de saber como usá-las com C# ou Visual Basic em seu aplicativo da Plataforma Universal do Windows (UWP).Most of the asynchronous APIs in the UWP don't have synchronous counterparts, so you need to be sure to understand how to use the asynchronous APIs with C# or Visual Basic in your Universal Windows Platform (UWP) app. Nós vamos mostrar como chamar as APIs assíncronas da UWP.Here we show how to call asynchronous APIs of the UWP.

Usando APIs assíncronasUsing asynchronous APIs

Por convenção, os métodos assíncronos recebem nomes que terminam em "Async".By convention, asynchronous methods are given names that end in "Async". Você normalmente chama APIs assíncronas em resposta à ação de um usuário, como, por exemplo, quando o usuário clica em um botão.You typically call asynchronous APIs in response to a user's action, such as when the user clicks a button. Chamar um método assíncrono em um manipulador de eventos é uma das maneiras mais simples de usar APIs assíncronas.Calling an asynchronous method in an event handler is one of the simplest ways of using asynchronous APIs. Aqui, usamos o operador de espera como exemplo.Here we use the await operator as an example.

Suponha que você tenha um aplicativo que lista os títulos das postagens de um blog de um determinado local.Suppose that you have an app that lists the titles of blog posts from a certain location. O aplicativo tem um Botão em que o usuário clica para obter os títulos.The app has a Button that the user clicks to get the titles. Os títulos são exibidos em um Bloco de Texto.The titles are displayed in a TextBlock. Quando o usuário clica no botão, é importante que o aplicativo continue respondendo enquanto aguarda a informação do site do blog.When the user clicks the button, it is important that the app remains responsive while it waits for the info from the blog's website. Para garantir essa capacidade de resposta, a UWP fornece um método assíncrono, SyndicationClient.RetrieveFeedAsync, para baixar o feed.To ensure this responsiveness, the UWP provides an asynchronous method, SyndicationClient.RetrieveFeedAsync, to download the feed.

O exemplo a seguir obtém as listas de postagens de um blog chamando o método assíncrono, SyndicationClient.RetrieveFeedAsync, e aguardando o resultado.The example here gets the lists of blog posts from a blog by calling the asynchronous method, SyndicationClient.RetrieveFeedAsync, and awaiting the result.

// 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.There are a couple of important things about this example. Primeiro, a linha SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) usa o operador de espera com a chamada para o método assíncrono, RetrieveFeedAsync.First, the line, SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) uses the await operator with the call to the asynchronous method, RetrieveFeedAsync. Você pode pensar no operador de espera dizendo ao compilador que está chamando um método assíncrono, o que faz com que o compilador realize um trabalho extra para que você não precise fazê-lo.You can think of the await operator as telling the compiler that you are calling an asynchronous method, which causes the compiler to do some extra work so you don’t have to. Em seguida, a declaração do manipulador de eventos inclui a palavra-chave async.Next, the declaration of the event handler includes the keyword async. Você deve incluir essa palavra-chave na declaração de método de qualquer método em que usar o operador de espera.You must include this keyword in the method declaration of any method in which you use the await operator.

Neste tópico, não entraremos em muitos detalhes sobre o que o compilador faz com o operador de espera, mas examinemos o que seu aplicativo faz para permanecer assíncrono e responsivo.In this topic, we won't go into a lot of the details of what the compiler does with the await operator, but let's examine what your app does so that it is asynchronous and responsive. Considere o que acontece quando você usa o código síncrono.Consider what happens when you use synchronous code. Por exemplo, suponha que exista um método chamado SyndicationClient.RetrieveFeed que seja síncrono.For example, suppose that there is a method called SyndicationClient.RetrieveFeed that is synchronous. (Esse método não existe, mas imagine que exista.) Se seu 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 de retorno RetrieveFeed estivesse disponível.(There is no such method, but imagine that there is.) If your app included the line SyndicationFeed feed = client.RetrieveFeed(feedUri), instead of SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri), execution of the app would stop until the return value of RetrieveFeed is available. Além disso, enquanto seu aplicativo aguarda a conclusão do método, ele não pode responder a nenhum outro evento, como outro evento Click.And while your app waits for the method to complete, it can't respond to any other events, such another Click event. Ou seja, seu aplicativo fica bloqueado até que RetrieveFeed seja retornado.That is, your app would be blocked until RetrieveFeed returns.

Mas, se você chamar client.RetrieveFeedAsync, o método iniciará a recuperação e será retornado imediatamente.But if you call client.RetrieveFeedAsync, the method initiates the retrieval and immediately returns. Quando você usa espera com RetrieveFeedAsync, o aplicativo sai temporariamente do manipulador de eventos.When you use await with RetrieveFeedAsync, the app temporarily exits the event handler. Dessa forma, ele pode processar outros eventos enquanto RetrieveFeedAsync é executado de maneira assíncrona.Then it can process other events while RetrieveFeedAsync executes asynchronously. Isso mantém o aplicativo responsivo para o usuário.This keeps the app responsive to the user. Quando RetrieveFeedAsync é finalizado e SyndicationFeed está disponível, o aplicativo basicamente volta a entrar no manipulador de eventos de onde saiu, depois de SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri), e conclui o restante do método.When RetrieveFeedAsync completes and the SyndicationFeed is available, the app essentially reenters the event handler where it left off, after SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri), and finishes the rest of the method.

A vantagem de usar o operador de espera é que o código não parece muito diferente daquele que utiliza o método imaginário RetrieveFeed.The nice thing about using the await operator is that the code doesn't look much different from how the code looks if you used the imaginary RetrieveFeed method. Existem maneiras de escrever código assíncrono em C# ou Visual Basic sem o operador de espera, mas o código resultante tende a enfatizar os mecanismos de execução de maneira assíncrona.There are ways to write asynchronous code in C# or Visual Basic without the await operator, but the resulting code tends to emphasize the mechanics of executing asynchronously. Isso torna o código assíncrono difícil de escrever, entender e manter.This makes asynchronous code hard to write, hard to understand, and hard to maintain. Utilizando o operador de espera, você obtém os benefícios de um aplicativo assíncrono sem tornar o seu código complexo.By using the await operator, you get the benefits of an asynchronous app without making your code complex.

Tipos de retorno e resultados de APIs assíncronasReturn types and results of asynchronous APIs

Se você tiver seguido o link para RetrieveFeedAsync, deve ter notado que o tipo de retorno de RetrieveFeedAsync não é um SyndicationFeed.If you followed the link to RetrieveFeedAsync, you might have noticed that the return type of RetrieveFeedAsync is not a SyndicationFeed. Em vez disso, o tipo de retorno é IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>.Instead, the return type is IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>. Exibida como sintaxe simples, uma API assíncrona retorna um objeto que contém o resultado no seu interior.Viewed from the raw syntax, an asynchronous API returns an object that contains the result within it. Embora seja comum, e às vezes útil, pensar em um método assíncrono como sendo aguardado, o operador de espera trabalha, na realidade, no valor de retorno do método, não no método.While it is common, and sometimes useful, to think of an asynchronous method as being awaitable, the await operator actually operates on the method’s return value, not on the method. Quando você aplica o operador de espera, o que obtém é o resultado da chamada de GetResult no objeto retornado pelo método.When you apply the await operator, what you get back is the result of calling GetResult on the object returned by the method. No exemplo, o SyndicationFeed é o resultado de RetrieveFeedAsync.GetResult().In the example, the SyndicationFeed is the result of RetrieveFeedAsync.GetResult().

Ao usar um método assíncrono, você pode examinar a assinatura para ver o que receberá depois de aguardar o valor retornado pelo método.When you use an asynchronous method, you can examine the signature to see what you’ll get back after awaiting the value returned from the method. Todas as APIs assíncronas na UWP retornam um dos seguintes tipos:All asynchronous APIs in the UWP return one of the following types:

O tipo de resultado de um método assíncrono é o mesmo que o parâmetro do tipo TResult.The result type of an asynchronous method is the same as the TResult type parameter. Os tipos sem um TResult não têm um resultado.Types without a TResult don't have a result. Você pode pensar no resultado como sendo nulo.You can think of the result as being void. No Visual Basic, um procedimento Sub é equivalente a um método com um tipo de retorno nulo.In Visual Basic, a Sub procedure is equivalent to a method with a void return type.

A tabela abaixo dá exemplos de métodos assíncronos e lista o tipo de retorno e o tipo de resultado de cada um.The table here gives examples of asynchronous methods and lists the return type and result type of each.

Método assíncronoAsynchronous method Tipo de retornoReturn type Tipo de resultadoResult type
SyndicationClient.RetrieveFeedAsyncSyndicationClient.RetrieveFeedAsync IAsyncOperationWithProgress < SyndicationFeed, RetrievalProgress>IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> SyndicationFeedSyndicationFeed
FileOpenPicker.PickSingleFileAsyncFileOpenPicker.PickSingleFileAsync IAsyncOperation < StorageFile>IAsyncOperation<StorageFile> StorageFileStorageFile
XmlDocument.SaveToFileAsyncXmlDocument.SaveToFileAsync IAsyncActionIAsyncAction voidvoid
InkStrokeContainer.LoadAsyncInkStrokeContainer.LoadAsync IAsyncActionWithProgress < UInt64>IAsyncActionWithProgress<UInt64> voidvoid
DataReader. LoadAsyncDataReader.LoadAsync DataReaderLoadOperation, uma classe de resultados personalizada que implementa IAsyncOperation<UInt32>DataReaderLoadOperation, a custom results class that implements IAsyncOperation<UInt32> UInt32UInt32

 

Métodos assíncronos que são definidos em .NET para aplicativos UWP têm o tipo de retorno Tarefa ou Task<TResult>.Asynchronous methods that are defined in .NET for UWP apps have the return type Task or Task<TResult>. Os métodos que retornam Tarefa são semelhantes aos métodos assíncronos na UWP que retornam IAsyncAction.Methods that return Task are similar to the asynchronous methods in the UWP that return IAsyncAction. Em cada caso, o resultado do método assíncrono é nulo.In each case, the result of the asynchronous method is void. O tipo de retorno Task<TResult> é semelhante ao IAsyncOperation<TResult> no sentido de que o resultado do método assíncrono ao executar a tarefa é do mesmo tipo do parâmetro tipo TResult.The return type Task<TResult> is similar to IAsyncOperation<TResult> in that the result of the asynchronous method when running the task is the same type as the TResult type parameter. Para saber mais sobre como usar .NET para aplicativos UWP e tarefas, veja Visão geral do .NET para aplicativos do Windows Runtime.For more info about using .NET for UWP apps and tasks, see .NET for Windows Runtime apps overview.

Tratando errosHandling errors

Ao usar o operador de espera para recuperar seus resultados de um método assíncrono, você pode usar um bloco tentativa/obtenção para manipular erros que ocorrem em métodos assíncronos, da mesma forma que você faz para os métodos síncronos.When you use the await operator to retrieve your results from an asynchronous method, you can use a try/catch block to handle errors that occur in asynchronous methods, just as you do for synchronous methods. O exemplo anterior encapsula o método RetrieveFeedAsync e a operação de espera num bloco tentativa/obtenção para manipular erros quando uma exceção é acionada.The previous example wraps the RetrieveFeedAsync method and await operation in a try/catch block to handle errors when an exception is thrown.

Quando métodos assíncronos chamam outros métodos assíncronos, qualquer método assíncrono que resulta numa exceção será propagado para os métodos externos.When asynchronous methods call other asynchronous methods, any asynchronous method that results in an exception will be propagated to the outer methods. Isso significa que você pode colocar um bloco tentativa/obtenção no método mais externo para encontrar erros para os métodos assíncronos aninhados.This means that you can put a try/catch block on the outer-most method to catch errors for the nested asynchronous methods. Novamente, isso é semelhante à maneira como você obtém exceções para métodos síncronos.Again, this is similar to how you catch exceptions for synchronous methods. Porém, não é possível usar espera no bloco obtenção.However, you can't use await in the catch block.

Dica    Começando com o C# no Microsoft Visual Studio 2005, você pode usar Await no bloco Catch .Tip  Starting with C# in Microsoft Visual Studio 2005, you can use await in the catch block.

Resumo e próximas etapasSummary and next steps

O padrão de chamada de um método assíncrono que mostramos aqui é o mais simples de usar quando você chama APIs assíncronas em um manipulador de eventos.The pattern of calling an asynchronous method that we show here is the simplest one to use when you call asynchronous APIs in an event handler. Você também pode usar esse padrão quando chamar um método assíncrono em um método substituído que retorna nulo ou um Sub no Visual Basic.You can also use this pattern when you call an asynchronous method in an overridden method that returns void or a Sub in Visual Basic.

Quando você encontrar métodos assíncronos na UWP, é importante ter em mente os seguintes pontos:As you encounter asynchronous methods in the UWP, it is important to remember:

  • Por convenção, os métodos assíncronos recebem nomes que terminam em "Async".By convention, asynchronous methods are given names that end in "Async".
  • Qualquer método que use o operador de espera deve ter sua declaração marcada com a palavra-chave async.Any method that uses the await operator must have its declaration marked with the async keyword.
  • Quando encontra o operador de espera, o aplicativo continua respondendo à interação do usuário enquanto o método assíncrono é executado.When an app finds the await operator, the app remains responsive to user interaction while the asynchronous method executes.
  • Aguardar o valor retornado por um método assíncrono retorna um objeto que contém o resultado.Awaiting the value returned by an asynchronous method returns an object that contains the result. Na maioria dos casos, o resultado contido no valor de retorno é o que é útil, e não o valor de retorno propriamente dito.In most cases, the result contained within the return value is what's useful, not the return value itself. É possível encontrar o tipo do valor contido dentro do resultado, observando o tipo de retorno do método assíncrono.You can find the type of the value that is contained inside the result by looking at the return type of the async method.
  • O uso de APIs assíncronas e padrões async costuma ser uma maneira de aprimorar a resposta de seu aplicativo.Using asynchronous APIs and async patterns is often a way to improve the responsiveness of your app.

O exemplo neste tópico envia um texto com essa aparência.The example in this topic outputs text that looks like this.

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