Asynchronous Programming For Windows Phone 8
Windows Phone 8 brings a lot of new features to developers and behind the scenes there are also some major improvements. The .NET framework 4.5 and the new C# compiler come with several major new features. Networked applications had to rely - in the past - on callbacks, but with the new asynchronous programming capabilities on the windows phone platform, the compiler can make some magic happen and increase productivity.
Article Metadata
Code Example
Tested with
Compatibility
Platform Security
Article
Contents |
What is asynchronous Programming?
In a console application, with the full .Net framework, to download data from an URL with a WebClient you can do
var client = new WebClient();
// Download data.
var textData = client.DownloadString("http://www.myurl.com/myFile.txt");
// Write values.
Debug.WriteLine(textData);
In graphical applications - unlike console applications where the whole execution flow can be driven from a single thread, including all I/O – , the execution flow often ends up being event driven. That means you start your logic after an event (click on a button or application loaded) and instead of waiting for something to complete you have to write more event handling to do something after the completion of your action.
With Windows Phone, only the asynchronous version of all I/O operations are available and it forces you to write code like this to accomplish the same task:
...
var client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(loadHTMLCallback);
client.DownloadStringAsync(new Uri("http://www.myurl.com/myFile.txt"));
...
public void loadHTMLCallback(Object sender, DownloadStringCompletedEventArgs e)
{
var textData = (string)e.Result;
// Do cool stuff with result
Debug.WriteLine(textData);
}
What is the difference?
Obviously the asynchronous case did increase the complexity and number of lines quite dramatically. We already jumped from one line to 6 to achieve the same result. In the first case, the execution thread has to wait all the required time to download the URL (remember network can be slow) and it holds its resources while it waits. In the second example with the asynchronous case, all the resources can be released after DownloadStringAsync and the thread calling this method can continue its execution. The thread that runs the UI code is generally the dispatcher thread and you should let it continue processing other interactions, otherwise your UI will freeze until you finish your method.
Asynchronous programming in C# 5.0
Asynchronous programming for .Net adds two new keywords: async and await. Inside an asynchronous context (in general this is simply within another asynchronous method), you can call an asynchronous method in a synchronous way by simply prefixing it with await. Behind the scenes, instead of holding the execution thread to wait for the result (in most cases a network call), the compiler will create callbacks to process the results (and the caller’s thread resources will be released). Essentially await is blocking, but only in the current function - from the perspective of the calling function life continues on until it too is forced to await something.
UI events have already an asynchronous context so all you need to do is add async to your event handlers to make your methods asynchronous and call other asynchronous events. So in this initial example, if DownloadString was asynchronous (I will show later how this can be done), we could write
var client = new WebClient();
// Download data.
var textData = await client.DownloadString("http://www.myurl.com/myFile.txt");
// Write values.
Debug.WriteLine(textData);
and it would be the exact equivalent of the version with callbacks.
In the synchronous version, the thread #1 has to wait and download the URL (remember network can be slow). In the second example with the asynchronous case, the caller from Thread #1 (calling this method in an asynchronous context) can continue its execution right before await client.DownloadString.
In the most common cases, the asynchronous methods are UI events and the caller is the dispatcher. In the first case, the UI would be frozen waiting for the download to complete, while in the second case the Thread #1 can continue executing other UI events, the rest of the code is executed by a new thread (Thread #2) once the download has completed.
In C#, the actual signature of DownloadString has to return a Task<string> instead of a string, the compiler with the await are doing the rest of the magic for you.
With any real world network service, you will have a complex workflow to handle (see Toodledo syncing for an example) and you are probably looking at writing at least 10 callback methods which does really add to the complexity of code.
Converting existing methods into to C# asynchronous methods
TaskCompletionSource<T> is the easiest way to convert existing code into asynchronous. All you need to do is call TrySetResult, TrySetException and TrySetCanceled within the callback. The following example shows how we could convert the DownloadStringAsync into an asynchronous equivalent.
public static Task<string> DownloadString(Uri url)
{
var tcs = new TaskCompletionSource<string>();
var wc = new WebClient();
wc.DownloadStringCompleted += (s,e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wc.DownloadStringAsync(url);
return tcs.Task;
}
Asynchronous code for Windows Phone 7
async and await are only available out of the box and fully featured with Visual Studio 2012 and Windows Phone 8. If you haven't yet upgraded to VS 2010 and need the Asynchronous features, the Visual Studio Async CTP adds them to the compiler and visual studio. For Visual Studio 2012 and Windows Phone 7 there is the Microsoft.Bcl.Async nuget package that lets you use the same keywords with .NET 4.
The example
The solution attached to this article demonstrates these concepts with a real service: Toodledo. Toodledo is a neat service that manages to do lists with many nice features, its REST API is very similar to many other services. We will demonstrate how to use the asynchronous features on the following scenario:
- Lookup the toodledo user id using an email
- Obtain a session token using the user id
- List the tasks for the user id with the session token
More details on the REST API and the service can be found on http://api.toodledo.com
Toodledo with Windows Phone 7
Instead of writing all the REST calls with the plain WebClient, we will use a nice REST library that does all the deserialization work called RESTSharp. With RESTSharp, the code for getting the toodledo tasks would look a little like
...
var client = new RestClient("http://api.toodledo.com/2");
var request = new RestRequest("account/lookup.php", Method.GET);
client.ExecuteAsync(request, result =>
{
if (resp.StatusCode == System.Net.HttpStatusCode.OK)
getTokenId(resp.Value);
});
...
public void getTokenId(string userAccount)
{
var client = new RestClient("http://api.toodledo.com/2");
var request = new RestRequest("account/token.php", Method.GET);
client.ExecuteAsync(request, result =>
{
if (resp.StatusCode == System.Net.HttpStatusCode.OK)
loadTaskList(resp.Value);
});
}
Toodledo with asynchronous methods
I am cheating a bit here because for each method the actual REST calls are in the method body but this still demonstrates the potential:
var username = await getUsername(“email@eail.com”)
var token = await getToken(username);
var tasks = await getTasks(token);
...
public async Task<ToodledoToken> getToken(string userId)
{
var request = new RestRequest("account/token.php", Method.GET);
return (await ExecuteAsync<ToodledoToken>(request));
}
...
Adding more magic to the application
In a typical application, in addition to these request, you need to manage status message and progress indicators so you need to interleave some GUI code that will run on the dispatcher.
- Get the status and progress bar out of the way
In this example, I used the reactive framework to handle the progress bar and the status text,. You can learn more about it on … and …
- Wrap existing asynchronous methods to use the new keywords
Currently many libraries (like REST clients) are not updated yet to work with the new asynchronous framework so it is necessary to transform the callback based methods into the new world that uses Task<T> as return type. Here is how I used the TaskCompletionSource to do wrap a RestRequest into an asynchronous method:
private async Task<T> ExecuteAsync<T>(RestRequest request)
{
var tcs = new TaskCompletionSource<T>();
_client.ExecuteAsync(request, resp =>
{
var value = JsonConvert.DeserializeObject<T>(resp.Content);
if (value.ErrorCode > 0)
{
var ex = new ToodledoException(value.ErrorCode, value.ErrorDesc);
tcs.SetException(ex);
}
else
tcs.SetResult(value);
});
return await tcs.Task;
}
Learn more about Asynchronous Programming
Official Microsoft documentation
- Asynchronous Programming with Async and Await
- Async Performance: Understanding the Costs of Async and Await
- Control Flow in Async Programs (C# and Visual Basic)
I/O and more
Asynchronous features are not limited to I/O, in this other article you can learn how to use asynchronous code to simplify UI workflows.
Download the solution
The zipped solution for this example can be downloaded Media:WPTodo.zip
Thanks to Hamish Willee for his constructive comments and feedback.



Contents
R2d2rigo - Article theme
This is an interesting topic to write about, but you can't use it to compete in the current contest; only entries about new, Windows Phone 8 specific features are allowed.
And the Portable Libraries section should be reworded, since they were already available prior to VS2012, as a way to share code between Windows, WP7 and Xbox.r2d2rigo 23:36, 5 December 2012 (EET)
CadErik -
Thanks for feedback. I think asynchronous programming is sort of specific to windows phone 8. Unlike the full .net stack, you have no other way to write network calls - there are no synchronous versions of the I/O methods.CadErik 03:58, 6 December 2012 (EET)
Hamishwillee - Not an expert but ....
Hi CadErik
Let me prefix this by "I am not a WP or .NET expert".
Reviewing the literature await is new to Windows Phone 8 and from my understanding of articles like this one the value of await et al is to vastly simplify asynchronous programming by encapsulating much of the creation and daisy-chaining of asynchronous operations/call back boilerplate code.
So my take on this is that asynchronous programming (even for these APIs) always existed (since you can run synchronous operations in another thread), but what you cover here makes them much easier to write.
If I am correct that makes that makes this a valid "new feature" and hence valid competition entry. I do believe though that there are libraries that emulate the functionality for WP7 and these should be mentioned.
I would remove the concentration on visual studio 2012 and refer to these as .Net or platform features - from a user perspective on this wiki this is "new stuff I can use in WP8", and "hey, I can backport to WP7" so that is what I'd focus on - perhaps a title "Improved asynchronous programming in Windows Phone 8" or similar. I would also do something comparative showing the difference in way this programming using both methods so you can show the improvements.
I haven't reviewed this in detail, so apologies if I misunderstand. Note also that I am not the final judge - who might take a different view.
R2d2rigo - is my position reasonable?
Regards
Hamishhamishwillee 08:01, 6 December 2012 (EET)
R2d2rigo -
Well, looking that async/await is a new core feature of WP8 even already being available in W8, I'd consider it valid then. But as Hamishwillee says, I'd focus more the article in how this improves the programming model of WP8, and how projects like Microsoft.Bcl tries to backport this functionality to WP7.r2d2rigo 16:19, 6 December 2012 (EET)
Hamishwillee - R2d2rigo - thanks!
CadErik, R2d2rigo then summarised my view quite well in previous comment. I think this would be a very useful article if well done. http://labs.vectorform.com/2012/02/asynchronous-ui-development-in-winrt-silverlight-windows-phone-wpf-with-asyncawait-keywords-of-c-5-0/ is a good start on the topic but I'm sure it could be done even better and with your examples.
R2d2rigo, thanks for your advice/guidance.hamishwillee 01:23, 7 December 2012 (EET)
CadErik - Updated article
Hamishwillee - R2d2rigo, thanks alot for your feedback and references. I updated the article with references to the other articles and another section. Is the focus better?CadErik 06:50, 7 December 2012 (EET)
Hamishwillee - Yes
Hi CadErik
Yes, I think the focus is much better. I'm still don't completely understand how this works from this article, but that is perhaps a limitation in me. The judges are experts and will be able to assess this better.
I think the problem for me is that waiting is a blocking operation, so if you use one of these in a UI thread it looks like you'd be blocking the UI. It might not be the case - I'm envisaging the case where async operation is called if called in a button click handler - does the handler not then complete if await is called in a function in it? Or maybe I'm overcomplicating this - you just wouldn't wait ... but then how would you signal the UI it needs to update with a new property value. Too much Symbian C++ in my past
I would also add links to "official" documentation on await/async.
There is a missing placeholder here: "You can learn more about it on … and …"
Regards
Hamishhamishwillee 07:56, 13 December 2012 (EET)
CadErik -
Hamish,
Thanks for the great feedback! I added a diagram, does this answer your question? The handler will complete using a callback, but the code calling the handler will be able to continue its execution right after it sees the await.CadErik 07:20, 16 December 2012 (EET)
Hamishwillee - Thanks, the diagram helps
Hi
I did a lot more research and I believe I "get" it now. Essentially await is blocking, but only in the current function - from the perspective of the calling function life continues on until it too is forced to await something. I'm not completely comfortable with all the implications, but it is cool. More reading for me.
I think that "What is asynchronous Programming?" section is probably a little unclear, probably because that title doesn't really match the content - which is about two different forms of asynchronous programming (with callbacks and using the new methods). Then there is some feel of repetition in the next section. Too late for the competition, but this section should probably follow a logical flow showing "synchronous programming is easy because the logical flow is easy to follow", "asynchronous programming used to be hard, because you had all these callbacks, and never new when they would be called and how to daisy chain them", "now asynchronous programming is much easier, because you can write async programming like sync programming - within a function the code will appear to wait synchronously, but within the context of the rest of your code it is as though the function did complete - and you only wait where you "really" need the value.
this would then combine with parts of the next section.
Anyway, something for you to think about. The diagram you added does help.
Regards
Hamishhamishwillee 07:16, 19 December 2012 (EET)
CadErik -
This was a more ambitious article than I originally thought! Great feedback again! I incorporated couple comments as minor edits.CadErik 19:51, 19 December 2012 (EET)
Hamishwillee - Yes it is
When I get my head around this, and after my holidays, I may try tidy the introduction further myself. Sometimes it helps to be ignorant :-0
Regards
Hamishhamishwillee 02:24, 20 December 2012 (EET)