bringing async/await to callback based asynchronous interfaces

During the last week, I have been prototyping around a new dating/chat mobile application concept. Since I own an Android device it seemed natural to perform the prototyping on Android.

After playing around with some cross platform tools and the Android SDK itself, I decided to use Xamarin for the following reasons:

  • Xamarin is cross platform it supports Android, iOS and even UWP
  • Ability to use C# which is the language I am the most productive with
  • Ability to use the abstractions defined in the native SDK of the targeted platform, which brings a native look and feel to the application

I am currently building an MVP version of the Android application and I encountered a lot of asynchronous APIs (such as LocationManager and Facebook’s GraphRequest) that uses a callback based interface.

In this post we are going to see how to convert these callback based interfaces to Task based interfaces that we can use with async/await.

Introducing async/await and the Task Parallel Library is beyond the scope of this post, so if you are not familiar with these concepts you can take a look at these links first:

Callback based interfaces

The Android SDK is written in the Java programming language. In Java, continuations to asynchronous methods that returns to the caller immediately are specified via callback command object.

Consider the following hypothetical Java class that represent a data access object:

The getPersonAsync method performs a database lookup for a specific user by their id, this method accepts an object that implements the GetPersonCallback interface which defines the OnSuccess method.

When the result of the computation (Person object in the previous example) is available later in time, the OnSuccess method is called with the available Person object.

This kind of interface can be used as follows:

The getPersonAsync method is called with the a provided id and an instance of an anonymous class. The concept of anonymous classes allows to define and instantiate an object implementing an interface at the same time. This concept is usually not needed in C# since it provides support for lambda expressions, events and delegate objects.

This style of callback passing is not ideal especially in C# for two reasons:

  • We can’t conveniently create anonymous object as in Java so we have to separately define a class implementing the callback interface

  • This style of callback passing breaks the flow of the program and we have to jump from callback to callback to follow the execution

In C# we have support for the awaitable pattern and it would be nice if we could convert these async methods from accepting callbacks to returning Task objects.

from accepting callbacks to returning tasks

The System.Threading.Task namespace, home of the task parallel library, contains the TaskCompletionSource class which is key to the Task returning transition.

Consider the following C# class that wraps the previous PersonDAO:

In Xamarin, Java classes are usable in C# code through some mechanism involving the JNI(Java interface for using native code) so in the previous example we just reference objects of the PersonDAO java class and call methods on available in them.

The PersonDAOWrapper class defines the GetPersonAsync method that takes an id and returns a Task<Person>, this method starts by creating a TaskCompletionSource<Person> object which provides a legit Task property that can be returned to the caller. It also defines a SetResult method that allows to notify it that the result is available which will cause the returned task (via Task property) to contain the result.

In the previous example we use the callback based method by passing a callback object that notifies the task completion source when the result is available via the SetResult method.

As we previously pointed out, in C# we had to define a private class implementing the callback but thanks to the async/await constructs we don’t need to specify the subsequent steps inside the callback objects. Consider the following snippet, this is how GetPersonAsync is used:

Notice here how we used the await keyword in order to wait in a non blocking fashion for the result to be available. The “Do something with the result part” sits just after the asynchronous call as if the call was synchronous, in this fashion the flow of the program can be followed without jumping from callback to callback.

Since SomeMethod uses the await keyword it needs to be marked as async, usually async methods should return a Task or a Task<T> and returning void is discouraged.

I used void in the example to show that it is possible to sometime use void as a return type for async methods. In Xamarin specifically with Android, we usually need to use await under an Activity life-cycle method such as OnCreate or OnPause. Since we cannot change the returning type of these methods ( which is usually void) when overriding them, we just keep it as it is when making the life-cycle method async.

closing thoughts

The possibility to use the Android SDK classes and APIs with C# is a huge productivity boost, from my standpoint.

Being able to use Visual Studio, Linq, Extension Methods, async/await and all the nice C# features when developing cross platform mobile apps is very delightful.

The only complaint that I have regarding Xamarin so far is that the build and deploy process starts to take noticeable time to complete when the projects grows in size.