Home > C#, WinRT > How to expose async methods in a Windows Runtime Component

How to expose async methods in a Windows Runtime Component

21/03/2013

We need to follow precise rules when we develop a Windows Runtime Component. One of the most important is that we have restrictions on the types that can be exposed. For example, we can’t have public methods that return Task.

Suppose we have the following class inside a Windows Runtime Component:

public sealed class MyLibrary
{
    public async Task<string> GetUriContentAsync(string uri)
    {
        var httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(uri);

        return content;
    }
}

When we compile it, we’ll obtain the following error message:

Method ‘MyRuntimeComponent.MyLibrary.GetUriContent(System.String)’ has a parameter of type ‘System.Threading.Tasks.Task’ in its signature. Although this generic type is not a valid Windows Runtime type, the type or its generic parameters implement interfaces that are valid Windows Runtime types. Consider changing the type ‘Task’ in the method signature to one of the following types instead: Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation, or one of the other Windows Runtime async interfaces. The standard .NET awaiter pattern also applies when consuming Windows Runtime async interfaces. Please see System.Runtime.InteropServices.WindowsRuntime.AsyncInfo for more information about converting managed task objects to Windows Runtime async interfaces.

In particular, the message suggests us to “Consider changing the type ‘Task’ in the method signature to one of the following types”.

So, we need to return one of the allowed return types. An extension method defined on Task type greatly simplifies this. The idea is to creat a Task as usual, and then invoke this extension method to obtain a type that is valid for a Windows Runtime Component:

public sealed class MyLibrary
{
    public IAsyncOperation<string> GetUriContentAsync(string uri)
    {
        return this.GetUriContentAsynHelper(uri).AsAsyncOperation();
    }

    private async Task<string> GetUriContentAsynHelper(string uri)
    {
        var httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(uri);

        return content;
    }
}

The original GetUriContentAsync method is now a private helper method. Note that, as long as methods in Windows Runtime Component aren’t public, we don’t have any restrictions on return types. So, in this case it’s perfecly legal to return a Task.

Then, in the new version of GetUriContentAsync, we invoke the AsAsyncOperaion extension method on the result of GetUriContentAsyncHelper to obtain an IAsyncOperation object. It is a valid Windows Runtime return type that represents an asynchronous operation.

In this way, in a Windows Store app we can write, as usual:

private async void button_Click(object sender, RoutedEventArgs e)
{
    MyLibrary lib = new MyLibrary();
    var content = await lib.GetUriContentAsync("https://marcominerva.wordpress.com");

    // ...
}
Categories: C#, WinRT
  1. 02/04/2013 at 15:05

    What I try this method I get the following error: ”await’ requires that the type ‘Windows.Foundation.IAsyncOperation’ have a suitable GetAwaiter method. Are you missing a using directive for ‘System’?’

    This is thrown from my rt component if I use the IAsyncOperation as a result type from the class library, any thoughts?

    • 05/04/2013 at 08:24

      Have you included the “using System” directive at the top of the file?

      • 05/04/2013 at 09:46

        I had not, and that sorted it, thanks! I’ve seen this before when VS doesn’t pull in a ‘using’ you want on an extension method😦

  1. 21/03/2013 at 12:28
Comments are closed.
%d bloggers like this: