Thursday, November 1, 2012

Unit Testing a Windows 8 Application

I am a big fan of test driving an application. That's why I write almost no code without writing a test for it.

I recently began writing a Windows Store application for Windows 8 and again wanted to test drive this app.   If you look at MSDN at how to add a test project to you Windows 8 app, you will see, you can add a Windows Store test project to your solution. Now, handy as this is, the down sight is that this test project is as well a Windows Store project type, meaning you won't be able to add a whole bunch of references to it. I wasn't able to add RhinoMock or Moq to it, nor was I able to add MSpec. The problem being these frameworks were build to the wrong version of the .Net framework.

Now, I could have made my own builds of the frameworks I am happy working with, but I started looking if there is no other way, like using a simple class library for unit testing a Windows Store app. Now, when you try this, the problem is, you can't get a reference of your Windows Store app added to your class library for testing.

To get this fixed, I tried out a couple of things. First I tried adding the same references to my class library project as were in the Unit Test Library for Windows Store apps. This didn't work, however. Also, I couldn't find the '.NET for Windows Store apps' reference dll. I also tried playing around with the output type of my project. Changing it to something different than class library. But then again, adding the necessary unit testing references became a problem. I also played around with the conditional compilation symbols (hey, I was trying to find where the differences lay between my own class library and a Unit Test Library for Windows Store apps).

After trying all that, I unloaded my project from solution explorer and started editing it, comparing it to the Unit Test Library for Windows Store apps and trying out different combinations. Now, after a couple of tries, the setting in your project file, you need is the following:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />

You can put this line as a replacement of the other csharp.targets file at the bottom of your project file. Once you have added this, you can add a reference of your Windows Store app to your class library. You will even see the '.NET for Windows Store apps' reference show up in your references. You will even be able to add all the additional references you want, like NUnit, Moq or RhinoMock, ...

One additional problem I had was with the System.Data dll, which was build to a different framework. Since I didn't need it in my test project, I happily removed it.


Monday, September 3, 2012

WCF on IIS and Windows 8

Just spend some time getting a simple WCF service up and running under IIS on my Windows 8 machine. Apparently, if you install IIS after installing the last .NET framework (ie. installing Visual Studio 2012), not all necessary handlers, adapters and protocols for WCF are installed on your IIS.

First time I tried to reach the WCF service it gave me an error that said 'The page you are requesting cannot be served because of the extension configuration.' This means you need to run Servicemodelreg.exe to reregister WCF (same kind of registration you needed from time to time for ASP .NET on previous versions of IIS, remember aspnet_regiis). You can find this tool at C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation for version 3.0 or at C:\Windows\Microsoft.NET\Framework\v4.0.30319 for version 4.0.

Now looking at the MSDN site, they will tell you to run the 3.0 version. After doing so, however, you won't have the necessary handlers installed for a WCF service created with Visual Studio 2012, since they are all version 4.0. So that won't work.

Running the 4.0 version however won't work either. If you try Servicemodelreg.exe -i it will tell you to register with the -c option (register a component). If you try the -i -c option you will get the error (and the solution!) that this tool cannot be used on this version of windows. What you can use, though, is the 'Turn Windows Features On/Off' dialog.

So simply open this up from your control panel (I pinned my control panel to my start page on day one of installing Windows 8, otherwise I wouldn't be able to find it again) and check the necessary WCF features you want to have available on your WCF. In most cases, just flagging HTTP will do. You can find the WCF features under .NET Framework 4.5 Advanced Services.


And that's what you need to get yuor WCF service running under IIS on Windows 8. Hope this was helpful.

Addendum: This fix recently also solved the issue of a 'HTTP Error 400. The request hostname is invalid' error of a colleague when trying to run a WCF service on Windows 8.

Saturday, July 14, 2012

Knockout an MVC Ajax call

I recently needed to build an Ajax data search, showing the result of the search in an MVC web page. Great opportunity, I thought, to give Knockout.js a try. Knockout.js lets you apply databindings to a web page and for this it uses an MVVM (Model View ViewModel) approach.

On the knockout site, you can find some great examples to get started, even give it a try in jsFiddle. But since my solution is a bit different from their tutorials, I wanted to share it with you.

The actual problem at hand was a page on which I needed to link a scanned in document to a dossier. Most of the times the number of the dossier can be picked up from the scanned in document, but this is not always the case. In case where the number of the dossier can't be determined from the scan, we want our users to go look for the dossier and link the dossier manually to the scanned in document.


The page to do this more or less looks like this (I rebuild the solution without most of the formatting we have in the initial application).



The initial setup for this contains a ScanController that gives you this Scan Detail page.

public class ScanController : Controller
{
        public ActionResult Detail(int id)
        {
            var scan = new Scan
                        {
                            Id = id,
                            File = "This is the file",
                            DossierId = 0,
                            DossierNumber = string.Empty
                        };
            return View(new ScanViewModel(scan, new Dossier()));
        }
}

This uses the Detail view, which consists of two divs for the accordion. The top div looks like this:

@using (Html.BeginForm("Link", "Scan"))
{
  &lt;div>
    &lt;fieldset>
      &lt;dl>
        &lt;h2>Scan info&lt;/h2>
        @Html.Label("Receipt date") 
        @Html.TextBox("receiptdate", string.Empty, new { @class = "date"  })                
      &lt;/dl>
      &lt;h2>Dossier info&lt;/h2>
      &lt;div>
        @Html.Hidden("file", Model.Scan.File)

        &lt;div id="linkDiv" @(Model.Scan.DossierId == 0 ? "class=hidden" : "")>
          &lt;div>Dossier: &lt;span id="dossierNumberText">@Model.Scan.DossierNumber&lt;/span>&lt;/div>
          @Html.Hidden("dossierNumber", Model.Scan.DossierNumber)
          &lt;input type="submit" value="Link Scan to this dossier"/>
        &lt;/div>
        &lt;div id="message" @(Model.Scan.DossierId == 0 ? "": "class=hidden")>
          There is no dossier to link to. You should search for one.
        &lt;/div>
      &lt;/div>
  &lt;/fieldset>
  &lt;/div>      
}

The bottom div looks like this:


&lt;div id="search">
    @using(Html.BeginForm("Search", "Dossier", FormMethod.Post, new { @id = "dossierForm" }))
    {
        &lt;fieldset>
            &lt;dl>
                @Html.LabelFor(m => m.Dossier.DossierNumber) 
                @Html.TextBoxFor(m => m.Dossier.DossierNumber)
            &lt;/dl>
            &lt;dl>
                @Html.LabelFor(m => m.Dossier.OwnerLastName) 
                @Html.TextBoxFor(m => m.Dossier.OwnerLastName)
            &lt;/dl>
            &lt;dl>
                @Html.LabelFor(m => m.Dossier.OwnerFirstName) 
                @Html.TextBoxFor(m => m.Dossier.OwnerFirstName)
            &lt;/dl>
            &lt;dl>
                &lt;input type="submit" value="Search"/>
            &lt;/dl>
        &lt;/fieldset>
    }
&lt;/div>
&lt;div id="searchResult" class="hidden">
    &lt;table id="resultTable">
        &lt;thead>
            &lt;th>DossierNumber&lt;/th>
            &lt;th>OwnerLastName&lt;/th>
            &lt;th>OwnerFirstName&lt;/th>
            &lt;th>Detail&lt;/th>
            &lt;th>Link&lt;/th>
        &lt;/thead>
        &lt;tbody>
                    
        &lt;/tbody>
    &lt;/table>
&lt;/div>

It's this bottom div that we are most interested in. The top form (Search Dossier) will be used to perform an Ajax search. The result of this search will have to be shown in the table of the bottom searchResult div.

For this search I already added a Dossier controller with a Search action:

public class DossierController : Controller
{
  public ActionResult Search(DossierSearchViewModel searchVm)
  {
    return Json(new
                  {
                    Success = true,
                    Message = "All's ok",
                    Data = new List&lt;Dossier>
                            {
                              new Dossier
                                  {
                                    DossierNumber = "123abc",
                                    OwnerFirstName = "John",
                                    OwnerLastName = "Doe"
                                   },
                              new Dossier
                                  {
                                    DossierNumber = "456def",
                                    OwnerFirstName = "Jeff",
                                    OwnerLastName = "Smith"
                                  },
                              new Dossier
                                  {
                                    DossierNumber = "789ghi",
                                    OwnerFirstName = "Peter",
                                    OwnerLastName = "Jackson"
                                  },
                              new Dossier
                                  {
                                    DossierNumber = "321jkl",
                                    OwnerFirstName = "Carl",
                                    OwnerLastName = "Turner"
                                  },
                             }
                   });
  }
}

If you click the Search button you will be get to see the Json result in the Dossier/Search page. This is not what we want, this form should perform an asynchronous Ajax post. That's not yet the case. For this I used the JQuery forms plugin. Which has a handy ajaxForm method you can add to your form. (you could also use the mvc ajax extensions for this, they should already be in your initial MVC setup).

&lt;script type="text/javascript">
    $(function () {
        $("#dossierForm").ajaxForm({
            success: render_dossier_grid
        });
    });

    function render_dossier_grid(ctx) {
    }
&lt;/script>

All of the knockout magic can now be added in the render_dossier_grid function. Before we can do this, make sure to add the knockout.js files to your solution. This can be easily done using nuget. Reference them in your _layout file, so you can use them.

First, let's create a viewmodel. This will be nothing more than a list of dossiers we get back from our dossier search. Since we want to be able to add and remove items from this list and at the same time have our table automatically show the new items, we will use a knockout observable array. To have the databindings applied to your view, you should call applyBindings for your viewmodel.

$(function () {
    $("#dossierForm").ajaxForm({
        success: render_dossier_grid
    });

    ko.applyBindings(viewModel);
});

function render_dossier_grid(ctx) {
}

var viewModel = {
    dossiers: ko.observableArray([])
};

This viewModel can now be filled when we get the result of our Ajax call.

function render_dossier_grid(ctx) {
    $("#searchResult").removeClass("hidden");
    viewModel.dossiers.removeAll();
    viewModel.dossiers(ctx.Data);
    myAccordion.accordion("resize");
}

That's pretty easy. I just reset the dossiers observable array of the viewmodel and add the dossiers that come from the Ajax call. Last bit is having the JQuery accordion control perform a resize, just to get rid of any scroll bars.

Next step is actually binding this viewmodel to something. So, we need to specify in our view what data needs to go where. For this we will extend the table we have on our page.

&lt;table id="resultTable">
    &lt;thead>
        &lt;th>DossierNumber&lt;/th>
        &lt;th>OwnerLastName&lt;/th>
        &lt;th>OwnerFirstName&lt;/th>
        &lt;th>Detail&lt;/th>
        &lt;th>Link&lt;/th>
    &lt;/thead>
    &lt;tbody data-bind="foreach:dossiers">
        &lt;tr>
            &lt;td data-bind="text:DossierNumber">&lt;/td>
            &lt;td data-bind="text:OwnerLastName">&lt;/td>
            &lt;td data-bind="text:OwnerFirstName">&lt;/td>
            &lt;td>
                &lt;a data-bind="attr: {href: DetailLink}">Detail&lt;/a>
            &lt;/td>
            &lt;td>
                &lt;a href="#" data-bind="click: $parent.useDossier">Use this file for linking&lt;/a>
            &lt;/td>
        &lt;/tr>
    &lt;/tbody>
&lt;/table>

Adding the databindings is not that hard. I added a foreach binding, which will make a new table row for each dossier in the dossiers observable array. Each table row has its own binding for each td element. The first three are quite obvious. You can databind to the names of the properties of your domain (or MVC viewmodel) object.

For the second to last binding I added a databinding to the href attribute of an a tag. The DetailLink is a property on the Dossier domain object that gives you a link to Dossier/Detail/id.

The last one is a special binding to the click event of an a tag. It is bound to the useDossier function of the parent of the binding. The parent of our binding is the actual viewmodel. We still need to add this useDossier function:

var viewModel = {
    dossiers: ko.observableArray([]),

    useDossier: function (dossierVM) {
        var dossierNumber = dossierVM.DossierNumber;
        myAccordion.accordion({ active: 0 });
        $("#dossierNumber").val(dossierNumber);
        $("#dossierNumberText").text(dossierNumber);

        $("#linkDiv").removeClass('hidden');
        $("#message").addClass('hidden');
    }
};

In this function I use the viewmodel. In this case this is the actual row/dossier of the table. I take the DossierNumber of the current dossier and use it to set the value of the dossierNumber and dossierNumberText fields in the top piece of the accordion. I also do some extra bits to update the UI accordingly.

That's it, not much to it. I really like this knockout framework. I did have some trouble to get started at first, but once you know your way around the viewmodel, it's pretty easy to use.

The full code can be found on github.

Tuesday, May 22, 2012

Async VII: WinRT class library

In the previous post I talked about async from JavaScript. Now, for this I had to make a WinRT class library for my asynchronous RestCaller class, so this functionality could be used from a HTML5 JavaScript WinRT application. Now, once you do this, there are some things you need to know and some restrictions on the types you use for your publicly visible methods.

First of all you need to create a class library. Pretty simple, but once it's created, you need to change its' project type to WinMD file. This stands for Windows MetaData file.


Also, in the first version, my class library was called BlitzHiker.Lib. This name gave me runtime errors when called from JavaScript. At compile time everything was fine, but at runtime it would just crash for no reason. Removing the point from its' name fixed this.

Once I had the class library ready, I copied my RestCaller class to it and started compiling. The errors this gave were quite abundant. For starters, you are not allowed to use a return type of Task or Task&lt;T> in a WinMD file. This forced me to define all of my existing methods as private. Which made it all compile just fine. But then again, you're nothing with private methods, you need some public ones as well.

private async Task PublishHikeRequestTaskAsync(CancellationToken token)
{
    var hikeRequest = GetHikeRequest();

    try
    {
        var client = new HttpClient();

        var url = string.Format("{0}/HikeRequest", BASE_URL);
        var response = await client.PostAsync(url, await BuildJsonContent(hikeRequest), token);
        response.EnsureSuccessStatusCode();
    }
    catch (HttpRequestException exc)
    {
        var dialog = new MessageDialog(exc.Message);
        dialog.ShowAsync();
    }
}

For each of these private methods I needed to define a public wrapper. The return types you are allowed to use on them are AsyncAction (as a replacement for Task) and AsyncOperation&lt;T> (as a replacement for Task&lt;T>).

The original method gets called by using AsyncInfo.Run (this changed in the recent CTP, the original type used was AsyncInfoFactory, but that one's gone. If you watch the Build sessions on async, you'll see them use the AsyncInfoFactory, but that just won't work anymore).

public IAsyncAction PublishHikeRequestAsync()
{
    return (IAsyncAction)AsyncInfo.Run((ct) => PublishHikeRequestTaskAsync(ct));
}

You can also see me sending along a CancellationToken. Since it's not passed along to the PublishHikeRequestAsync method, you will have to use a different way of cancelling than I showed in one of the previous posts.

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    cts = new CancellationTokenSource();

    try
    {
        await _restCaller.PublishHikeRequestAsync().AsTask(cts.Token);

        var driverIds = await _restCaller.GetDriversAsync().AsTask(cts.Token);

        if (driverIds != null)
            await ShowDriversOnMap(driverIds, cts.Token,
                new Progress&lt;int>(p => statusText.Text = string.Format("{0} of {1}", p, driverIds.Count)));
    }
    catch (OperationCanceledException exc)
    {
        statusText.Text = exc.Message;
    }
}

Since you get an AsyncAction, and not a Task, you can call AsTask on this. With AsTask, you can send along your CancellationToken. This shows that before you all start using WinMD class libraries, just keep in mind that you are working with different types and that the usage will be different (more verbose) as well.

As for the AsyncOperation, that's pretty much the same as AsyncAction.

public IAsyncOperation&lt;UserModel> GetUserAsync(Guid userId)
{
    return (IAsyncOperation&lt;UserModel>)AsyncInfo.Run((ct) => GetUserTaskAsync(userId, ct));
}

And that's it. I hope you found these posts on async useful. Just keep in mind that all info given here is still based on a preview version of this library and things can still change a bit in the eventual release.

There are some drawbacks on using async. As with a lot in the .NET Framework, they make things really simple for you. The danger is that it's easy to forget what you are actually doing, defining callbacks. Just keep that in mind and you'll be fine.

Friday, May 18, 2012

Async VI: JavaScript Promises

The previous posts (Async basics, Exception handling, Cancellation, Progress reporting, void methods) all talked about async from a C# point of view. But let's not forget there is another very important language coming to WinRT and that's JavaScript in combination with HTML5. The cool thing is you can use more or less the same async capabilities here that you find in C#. Big difference is the syntax you will be using. Since the async syntax will be closer to what you are used to in JavaScript.

The UI in the JavaScript BlitzHiker application looks pretty much the same as its C# counterpart. It also has a page to publish a hikerequest, which does three big things, initialize the Bing map we use, find my own location and publish my hikerequest.

function initialize() {
    initializeBing();
    findMe();
    publish();
}

The findMe function has the first bit of asynchrony.

function findMe() {
    if (myPosition) {
        setMePushpin(myPosition)
    }
    else {
        if (!loc) {
            loc = Windows.Devices.Geolocation.Geolocator();
        }
        if (loc) {
            loc.getGeopositionAsync()
            .then(setMePushpin, errorHandler);
        }
    }
}

The call to GetGeopositionAsync is an asynchronous call. We can subscribe a callback to this method by using the then function. So no special keywords like await and async here, but more JavaScript style callbacks. You also see me using an error handler. In the JavaScript case, it is not with try catch that you handle exceptions, but with an extra error handler function you can send along.

I also made use in this function of the loc variable, that I defined globally. My original version of this method looked like this:

function findMe() {
    if (myPosition) {
        setMePushpin(myPosition)
    }
    else {
        Windows.Devices.Geolocation.Geolocator()
            .getGeopositionAsync()
            .then(setMePushpin, errorHandler);
    }
}

But funny enough only one times out of 10 the pushpin for my position was set correctly. This had me puzzled. Apparently, my local Geolocator had already gone out of scope before the callback came in. That is why I altered this to a global variable.

Another place where I used asynchronous callbacks, is in the publish method, which publishes a hikerequest, gets all the drivers and shows those on the Bing map.

function publish() {
    var caller = new BlitzHikerLib.RestCaller();
    caller.publishHikeRequestAsync()
    .then(function () {
        caller.getDriversAsync()
        .then(function (driverIds) {
            if (driverIds == null || driverIds.length == 0)
                return;
            for (var i = 0 ; i &lt; driverIds.length && i &lt; 200 ; i++) {
                var driverId = driverIds[i];
                caller.getUserAsync(driverId)
                .then(showDriver);
            }
        });
    });
}

You see me use then three times, each time sending a callback function along. Now, in my humble opinion, this syntax doesn't make this code the most readable code in the world. You need to look at it a couple of times to see what's going on. Now, you can actually improve on this by use of a little trick.

function publish() {
    var caller = new BlitzHikerLib.RestCaller();
    cancellable =
        caller.publishHikeRequestAsync()
        .then(function () {
            return caller.getDriversAsync()
        })
        .then(function (driverIds) {
            if (driverIds == null || driverIds.length == 0)
                return;
            for (var i = 0 ; i &lt; driverIds.length && i &lt; 200 ; i++) {
                var driverId = driverIds[i];
                caller.getUserAsync(driverId)
                .then(showDriver);
            }
        })
        .then(null, errorHandler);
}

You can see that for all but one, all then statements are nicely aligned. This can be done since we return the actual asynchronous call from the callback.

The reason I don't use this trick with GetUserAsync, is that, if I were to do that, I would jump out of the for loop that's processing each driver and only the first driver would be shown on the map.

The last then statement is special as well, since it defines a global error handler. Whatever error occurs in whatever callback, this error handler will catch it. Another useful trick.

I also extended this method a bit and actually caught the asynchronous calls in a variable, I called cancellable. Cancellation in JavaScript as well is done a bit differently. Once you define a global variable like this, you can call cancel on it.

function cancelHike() {
    if (cancellable != null) {
        cancellable.cancel();
        var errorDiv = document.getElementById("errorText");
        errorDiv.innerText = "operation cancelled";
    }
}

With this you have more or less the exact same application as I showed in the C# examples. But I do have to say I did need to alter some things in the RestCaller to get all this working for JavaScript. That is something I'll show you in the next (and last) blog post.

Thursday, May 17, 2012

Async V: void methods

In the previous post on async, I told you, we would go a bit deeper into void methods, since they behave differently than methods returning a Task or Task<t>. The difference is that, where non-void returning methods give you callback behavior, void methods give you fire and forget behavior. This can give you confusing results if you don't know how to spot and use them.

Let's take a look again at our OnNavigatedTo method.

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);
}

Now, the original version of this code looked a bit different, I actually altered it to get the entire explanation on async right for you. The original version was actually written as follows:

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

    var driverIds = await _restCaller.GetDrivers();

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

    var hikerIds = await _restCaller.GetHikers();

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

The difference here is that I didn't use await on the calls to ShowDriversOnMap and ShowHikersOnMap. The reason for this is that while writing this code, I had made these two methods void. You are not allowed to use the await keyword on a void method.

private async void ShowDriversOnMap(List<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);
    }
}

The usage of void for these methods makes very much sense to me. You are just showing something on a UI, no need for these two methods to return anything, right? Well, indeed, right, but what I didn't expect was that the behavior of these void methods was completely different from the Task returning methods. That is, void methods behave as fire and forget methods. You can't even use await on them, that is why those keywords when calling these methods are missing, not because I forgot them, but because you're not even allowed to use them. Your compiler will complain if you do.

The behavior you get in this case, is that, while the drivers are being shown on the map, since this call is fire and forget, the processing already continues with fetching all the hikers and showing those on the map as well. So you actually get parallel behavior and not callback behavior. In the case of showing the drivers and hikers on the map simultaneously, this might not seem such a big of a problem, but I can imagine cases in which it does present a problem.

What is even a bigger problem is that for void methods you don't even have a clue that you are calling an async method. With Task and Task<T> returning methods you get a nice tooltip that says you are using an awaitable.


With void returning async methods, you get none of this. The tooltip just says it's a void method, you have no clue of the fire and forget behavior.


That is why, as far as async goes, it is recommended you always use Task or Task<T> returning methods, these ones give you callback behavior. The void returning methods are recommended for use only on event handlers.

If using Task returning methods, you can also get parallel behavior. For this, you can use the WhenAll method on the Task class.


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

    var driverIds = await _restCaller.GetDrivers();

    var hikerIds = await _restCaller.GetHikers();

    var showDriversTask = ShowDriversOnMap(driverIds);

    var showHikersTask = ShowHikersOnMap(hikerIds);

    Task.WhenAll(showDriversTask, showHikersTask);
}

Both tasks will be executed in parallel and execution of the rest of the method will continue when both tasks are finished. Another handy method on the Task class is the WhenAny method. It behaves more or less the same as WhenAll, but it continues with the rest of the method body as soon as one of tasks you give it as a parameter finishes.

Next post we will look at using async methods from JavaScript in WinRT.

Friday, May 4, 2012

Async IV: Progress Reporting

In the previous post, I already told you that progress reporting for asynchronous calls can be done by using the IProgress interface. This interface has a Report method with which you can report progress. You probably already saw me using the IProgress interface in the previous post, but now let's explain what actually happens.


protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    cts = new CancellationTokenSource();

    try
    {
        await _restCaller.PublishHikeRequest(cts.Token);

        var driverIds = await _restCaller.GetDrivers(cts.Token);

        if (driverIds != null)
            await ShowDriversOnMap(driverIds, cts.Token,
                new Progress<int>(p => statusText.Text = string.Format("{0} of {1}", p, driverIds.Count)));

        var hikerIds = await _restCaller.GetHikers(cts.Token);

        if (hikerIds != null)
            await ShowHikersOnMap(hikerIds, cts.Token);

    }
    catch (OperationCanceledException exc)
    {
        statusText.Text = exc.Message;
    }
}

The Progress class is an implementation of the IProgress interface. The integer generic type parameter I send along is the type of progress I want reported. In this case I just want an integer value, but you can even have progress reported in a type you have specially defined for this purpous. The constructor of the Progress class takes in a lambda expression for the progress reporting. In this case I just show the number of drivers already shown on the map in the text of a TextBox.

The reporting of progress itself is done in the ShowDriversOnMap method.

private async Task ShowDriversOnMap(List<Guid> driverIds, CancellationToken token = default(CancellationToken), IProgress<int> progress = default(IProgress<int>))
{
    var count = 0;
    foreach (var driverId in driverIds)
    {
        if (progress != null && count % 10 == 0)
            progress.Report(count);

        var driver = await _restCaller.GetUser(driverId, token);
        var pushpin = new Pushpin();
        pushpin.Text = "D";
        pushpin.Foreground = new SolidColorBrush(Colors.Green);
        pushpin.Tapped += async (s, args) =>
        {
            MessageDialog dialog = new MessageDialog(string.Format("This is {0}.", driver.FullName));
            await dialog.ShowAsync();
        };
        MapLayer.SetPosition(pushpin, new Location(driver.LatitudeFrom, driver.LongitudeFrom));
        MyMap.Children.Add(pushpin);

        count++;
    }
}

I report progress in steps of 10. Since the IProgress in this case takes an int generic type parameter, I just send along an integer value to the Report method.

With the techniques you've seen so far (basics, exception handling, cancellation and progress reporting), you can get started with using async. In the next posts we will go some steps further, though, we will look at what void asynchronous methods do and start using async calls from JavaScript code. For this we will also create a WinMD library, which changes some things, both for defining asynchronous methods as for using them.

But before you move on to that, let me first give you a couple of pointers to watch out for.

Using the asynchronous features is made extremely easy for you. This implies that often you use them, without really thinking about what you are actually doing (hey, you're defining a callback, remember). I have found that once you start using async, you really need to think about how your users will be using your application. This implies thinking about cancellation, so you don't keep processing unnecessary calls.

Also, at the end of the day you end up with quite some async methods in your code. Since every time you use await, you need to make your method async. And whatever calls you method, must use await and be made async as well, and so on.