Monday, April 30, 2012

Async I: The Basics

In the recent talk I gave for Visug, we looked at the new async capabilities in the next version of the .NET Framework. The slides of this session can be found here. In this series of posts, I would like to walk you through the different demo's I showed during this talk.

The demo's were actually a rewrite of an existing application, the Blitzhiker application, we've developed for Windows Phone. The rewrite is a port of this application to the Windows 8 runtime.

The Blitzhiker application itself tries to bring hikers (people looking for a ride) and drivers (people with a car) closer together.


Hikers can publish hikerequests and get an overview of drivers and other hikers nearby. Below you can see a screen shot after a hiker has published his request. A Bing map is shown with pushpins for each driver nearby. Since all calls are done asynchronously, the entire user interface stays responsive while pushpins are shown on the map.



First thing we will take a look at, is the basics of asynchronous calls. What makes up an asynchronous call and how does it affect the execution of your program.

The code to publish the hikerequest, show the drivers on the map and after that show the hikers on the map, looks like this:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    await _restCaller.PublishHikeRequest();

    var driverIds = await _restCaller.GetDrivers();

    if (driverIds != null) 
        await ShowDriversOnMap(driverIds);

    var hikerIds = await _restCaller.GetHikers();

    if (hikerIds != null) 
        await ShowHikersOnMap(hikerIds);
}

What happens is that we publish a hikerequest, after that, ask for all of the drivers on our route, next, show these guys on our map, then, get all of the hikers near us and show these on the map as well. The ShowDriversOnMap is a call that usually takes some time when there are a lot of drivers nearby. What we notice though is, that while showing the drivers, the entire application stays responsive, which is actually what we want from asynchronous calls.

You can spot the use of several awaits in the OnNavigatedTo method. What happens is that an await kicks of the execution of an asynchronous method and turns the rest of your method body into a callback. So in this piece of code several callbacks will be created at compile time, without you needing to mess up your code for this, you can keep on writing as if you are writing synchronous code.

What is also interesting about awaiting code this way, is that each callback will be executed in the same execution context that kicked of the asynchronous call. So, if you were on a UI thread, your callback will be executed on the UI thread. No need for Dispatcher.Invoke!

You probably noticed as well the use of the async keyword. This tells the compiler that the current method contains asynchronous calls and that there will probably need to be some extra compiler effort to create the necessary callbacks. Once you use the await keyword in a method, you need to put the async keyword in the method header. If you don't, your code won't compile. An async method can either have a void return type (as is the case in our piece of code) or can have a Task or Task<T> return type. Let's take a look at the ShowDriversOnMap method, which has a Task return type.

private async Task ShowDriversOnMap(List&lt;Guid> driverIds)
{
    foreach (var driverId in driverIds)
    {
        var driver = await _restCaller.GetUser(driverId);
        var pushpin = new Pushpin();
        pushpin.Text = "D";
        pushpin.Tapped += async (s, args) =>
        {
            MessageDialog dialog = 
                new MessageDialog(string.Format("This is {0}.", driver.FullName));
            await dialog.ShowAsync();
            MessageDialog secondDialog = 
                new MessageDialog("I am shown only after the previous dialog finishes.");
            await secondDialog.ShowAsync();
        };

        MapLayer.SetPosition(pushpin, 
            new Location(driver.LatitudeFrom, driver.LongitudeFrom));
        MyMap.Children.Add(pushpin);
    }
}

Again the await keyword is used, kicking of an asynchronous method and automatically turning the rest of the method body into a callback. You can also spot the use of the await keyword inside of a lambda expression. In WinRT there is no more DialogBox, but a MessageDialog. This one doesn't have a Show method, but a ShowAsync method, so, again, you can use await on this. Once you do this, you need to mark the lambda expression with the async keyword as well. I actually show 2 MessageDialogs with an await keyword. If you would set breakpoints in this lambda, you would spot the first dialog being shown and your code not starting to create the second dialog until you close the first one. That's the callback kicking in.

That's it for the basics of asynchronous calls. In a next post, we will go into exception handling and take a look at the RestCaller class that is being used in the code examples of this blog post.

Friday, April 13, 2012

JSON POST with ASP .NET Web API

I have been struggling a bit with porting existing Json calls to the new ASP .NET Web API framework. I actually got the GET request working pretty quickly, but it were the POST (and DELETE en PUT) requests that were giving me headaches. Problem is the current brevity and lack of practical examples for the Web API framework. So here goes a short example of getting a Json POST up and running.

For these examples I used the Visual Studio 2011 beta version.

Let's first start with the GET request. What you need for this is the HttpClient class, which can be found in the System.Net.Http namespace. This class provides methods like GetAsync, PutAsync, DeleteAsync and PostAsync. The 'Async' extensions let you know that you can use the new async and await keywords to get this up and running. A GET requests with the HttpClient consists of only two lines of code.

var client = new HttpClient();
var response = await client.GetAsync("http://some_url/resource_name/resource_id");
response.EnsureSuccessStatusCode();

All of this is contained in a method that has the extra async keyword. I also added the EnsureSuccessStatusCode call to verify my call to the REST service didn't fail. If the call fails the EnsureSuccessStatusCode will throw an exception. So you can easily wrap this piece of code in a try catch block.

So, that was quite easy. The GET call should work immediately.

On to the POST call. I actually want to post an object to our REST service. The previous version of the code I was porting to the Web API used the RestSharp (performs REST calls) and NewtonSoft.Json  (serializes from and to Json) frameworks to perform REST calls (both are available via NuGet). I started out reusing only NewtonSoft.Json, since the HttpClient class removes the need for the RestSharp framework. But is turned out I couldn't get the serialized Json object send to the service in a acceptable format. The service kept giving me 400 Bad Request messages. So I was doing something wrong.

After some searching I found there are a couple of different content class types you can use when performing a PostAsync. I used StringContent up untill then, but I needed a ObjectContent. The HttpRequestMessage class can create one for you. Moreover, the Web API contains its own Json formatters, so the need for the NewtonSoft library became obsolete.

var anObject = new MyObjectType
{
    SomeProperty = "some value"
};

try
{
    var client = new HttpClient(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var requestMessage = new HttpRequestMessage();
    var content = requestMessage.CreateContent&lt;MyObjectType>(
        anObject,
        MediaTypeHeaderValue.Parse("application/json"),
        new MediaTypeFormatter[] { new JsonMediaTypeFormatter() },
        new FormatterSelector());

    var response = await client.PostAsync("http://some_url/resource_name", content);
    response.EnsureSuccessStatusCode();
}
catch (Exception exc)
{
    Console.WriteLine(exc.Message);
}


And there you have it, my first successful Json POST message.