In this article

The Windows Runtime includes many asynchronous APIs to ensure that your app remains responsive when it does work that might take an extended amount of time. This means that your app doesn't need to wait for large operations to complete before continuing execution. For example, an app that downloads info from the Internet might spend several seconds waiting for the info to arrive. If you use a synchronous method to retrieve the info, the app is blocked until the method returns. The app won't respond to user interaction and because it seems non-responsive, the user might become frustrated. By providing asynchronous APIs, the Windows Runtime helps to ensure that your app stays responsive to the user when it's performing long operations.

Most of the asynchronous APIs in the Windows Runtime 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 Windows Runtime app. Here we show how to call asynchronous APIs of the Windows Runtime.

Prerequisites

Using asynchronous APIs

By convention, asynchronous methods are given names that end in "Async". You typically call asynchronous APIs in response to a user's action, such as when the user clicks a button. Calling an asynchronous method in an event handler is one of the simplest ways of using asynchronous APIs. Here we use the await operator as an example.

Suppose that you have an app that lists the titles of blog posts from a certain location. The app has a Button that the user clicks to get the titles. The titles are displayed in a TextBlock. 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. To ensure this responsiveness, the Windows Runtime provides an asynchronous method, SyndicationClient.RetrieveFeedAsync, to download the feed.

The example here gets the lists of blog posts from a blog by calling the asynchronous method, SyndicationClient.RetrieveFeedAsync. This is the simplest way to call an asynchronous method.

There are a couple of important things about this example. First, the line, SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) uses the await operator with the call to the asynchronous method, RetrieveFeedAsync. 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. Next, the declaration of the event handler includes the keyword async. You must include this keyword in the method declaration of any method in which you use the await operator. There's nothing about the Button.Click event handler signature that required the async keyword; async was added deliberately so that the compiler will permit calling asynchronous methods from the body of that handler. For more info about handling input events and running awaitable methods within them, see Events and routed events overview.

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. Consider what happens when you use synchronous code. For example, suppose that there is a method called SyndicationClient.RetrieveFeed that is synchronous. (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 stops until the return value of RetrieveFeed is available. And while your app waits for the method to complete, it can't respond to any other events, such another Click event. That is, your app would be blocked until RetrieveFeed returns.

But if you call client.RetrieveFeedAsync, the method initiates the retrieval and immediately returns. When you use await with RetrieveFeedAsync, the app temporarily exits the event handler. Then it can process other events while RetrieveFeedAsync executes asynchronously. This keeps the app responsive to the user. 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.

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. 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. This makes asynchronous code hard to write, hard to understand, and hard to maintain. By using the await operator, you get the benefits of an asynchronous app without making your code complex.

Return types and results of asynchronous APIs

If you followed the link to RetrieveFeedAsync, you might have noticed that the return type of RetrieveFeedAsync is not a SyndicationFeed. Instead, the return type is IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>. Viewed from the raw syntax, an asynchronous API returns an object that contains the result within it. 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. When you apply the await operator, you get the result of the asynchronous methods. Specifically, you get the result of calling GetResult on the object you see in the raw syntax. In the example, the SyndicationFeed is the result of RetrieveFeedAsync.

When you use an asynchronous method, you can get info about its result by looking at the return type. All asynchronous APIs in the Windows Runtime return one of the following types:

The result type of an asynchronous method is the same as the TResult type parameter. Types without a TResult don't have a result. You can think of the result as being void. In Visual Basic, a Sub procedure is equivalent to a method with a void return type

The table here gives examples of asynchronous methods and lists the return type and result type of each.

Handling errors

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. The previous example wraps the RetrieveFeedAsync method and await operation in a try/catch block to handle errors when an exception is thrown.

When asynchronous methods call other asynchronous methods, any asynchronous method that results in an exception will be propagated to the outer methods. This means that you can put a try/catch block on the outer-most method to catch errors for the nested asynchronous methods. Again, this is similar to how you catch exceptions for synchronous methods. However, you can't use await in the catch block.

Summary and next steps

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. 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.

As you encounter asynchronous methods in the Windows Runtime, it is important to remember:

By convention, asynchronous methods are given names that end in "Async".

Any method that uses the await operator must have its declaration marked with the async keyword.

When an app finds the await operator, the app remains responsive to user interaction while the asynchronous method executes.

An asynchronous method returns an object that contains its result. In most cases, the result from the return value is what's useful, not the return value itself. You can find the result type by looking at the return type.

Using asynchronous APIs and async patterns is often a way to improve the performance of your app. For more info on the performance benefits of using asynchronous APIs, see Keep the UI thread responsive; that topic specifically discusses implementing logic as a Task so that it's asynchronous.