First off let me start by saying the async framework isn’t destined to make you not want to use Reactive Extensions or a bunch of your own helpers … async framework was written with the purpose of simplifying your code when it comes to asynchronous tasks.
The async framework comes with a few extensions to existing classes and the extra TaskEx (which is only a temporary class – everything will be moved later on to the usual Task class) class which we’ll also talk about in this article.
The sample project is available here.
1st simple example:
For demo purposes I’m using the WebClient class although I’d recommend using HttpWebRequest (though WebClient should be enough for simple requests and the response will come back on the Background thread if you have created it on the Background thread ONLY WITH MANGO).
This is how an asynchronous task with a callback looks usually:
public static void Call(Action<IEnumerable<SubscriptionItem>> callback, string uri)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
callback(SubscriptionItem.ParseList(e.Result));
else
callback(null);
};
client.DownloadStringAsync(new Uri(YAHOO_BASE + uri, UriKind.Absolute));
}
SubscriptionItem is a class with a static method called ParseList which is only used to get an Enumerable of SubscriptionItem from the XML returned from Yahoo’s RSS (none relevant to our subject at hand!)
Let’s say we want to make our code a bit more fail proof, we’ll be adding in the callback an Exception.
public static void Call(Action<IEnumerable<SubscriptionItem>,Exception> callback, string uri)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
callback(SubscriptionItem.ParseList(e.Result),null);
else
callback(null,e.Error);
};
client.DownloadStringAsync(new Uri(YAHOO_BASE + uri, UriKind.Absolute));
}
Then running the method and getting the callback would look like this:
RandomServiceExample.Call((lstItems, error) =>
{
if (error == null)
{
//do something with our list
}
}, "business");
Now let’s complicate things a bit and say we wanted to retrieve the HTML from each link returned in the list of items:
RandomServiceExample.Call((lstItems, error) =>
{
if (error == null)
{
foreach (var item in lstItems)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, args) =>
{
//do something with the html returned
};
client.DownloadStringAsync(new Uri(item.Link, UriKind.Absolute));
}
}
}, "business");
Now I’ve used again the WebClient with another callback here as the simplest / fastest solution (of course not advisable solution) to prove 3 points:
- If you wanted to track / know when the html for all your items were all retrieved you’d be in a pickle with very ugly extra code (unless you’re using Rx, but that’ll be for another post).
- The code you’re reading gets uglier on the eyes!
- If in the callback of the WebClient you wanted to retrieve the item in lstItems on which you called upon, well you don’t have it/it changed…which would complicate things a little bit (you’d need to retrieve it someway through your callback):
In order to prove what I’m talking about add a Debug.WriteLine of the item.Link (the link we supposedly called) in the callback of the WebClient you’ll notice it’s the last item and not the item on which the client has supposedly finished to call.
So ….. how will the async framework help us with this dilemma ? Ask no more !
Get the bits here.
After the installation a bunch of the samples and documentation are available in your “Documents” folder, the folder is called: Microsoft Visual Studio Async CTP
Add the reference to the async dll for the windows phone which is found in the Samples folder: C:\Users\[YOURUSER]\Documents\Microsoft Visual Studio Async CTP\Samples\AsyncCtpLibrary_Phone.dll
Let’s make our code more readable shall we:
public static async Task<IEnumerable<SubscriptionItem>> CallAsync(string uri)
{
WebClient client = new WebClient();
string response = await client.DownloadStringTaskAsync(new Uri(YAHOO_BASE + uri, UriKind.Absolute));
return SubscriptionItem.ParseList(response);
}
BAM!
Chocker ha ? do you find it a lot more readable ? yes me too..
So this is the same asyc method “Call” I’ve written above but instead of writing the callbacks ourselves, well you’ve guessed using the “async” and “await” keywords its done kind of for us
..(the compiler gets its hands dirty for us..)
Now let me explain, why “Task” ? did you notice instead of returning just an “Enumerable<SubscriptionItem>” result I’m returning a generic “Task” of that type.
The “Task” generic class will help us determine whether the task was completed and even cooler whether an error occurred !
So instead of having the usual callback you have a representation of the “ongoing” work.
Here’s the msdn documentation of the “Task” class: http://msdn.microsoft.com/fr-fr/library/system.threading.tasks.task.aspx
Don’t be surprised by seeing: .NET Framework 4 under the title, the Task class does exist already ! (and you don’t need the async framework to use it on other stuff).
Back to our code, now you might notice “DownloadStringTaskAsync” instead of calling DownloadStringAsync.
This is the Task based method that comes with the async framework which returns an object of type Task<string> which itself also contains an exception in case one happened.
With the “await” keyword behind the method call we’re actually waiting for the call to finish before passing in it the response and going to that second line.
Now wait before you go all “say whaaaat??” on me..the current thread isn’t blocked here, what happens is the rest is assigned as a callback to the completed event.
Now to make our code a little bit more fail proof in case you wanted to test whether the WebClient itself has failed to Download the String:
public static async Task<IEnumerable<SubscriptionItem>> CallAsync(string uri)
{
WebClient client = new WebClient();
var task = client.DownloadStringTaskAsync(new Uri(YAHOO_BASE + uri, UriKind.Absolute));
await TaskEx.WhenAny(task);
if (task.Exception == null)
return SubscriptionItem.ParseList(task.Result);
else
return null;
}
IMPORTANT INFO:
When using the “await” keyword, it’s mandatory to have the “async” keyword behind the method from which your “await” is invoked.
As an example here’s how the MainPage Load event would look like with the call.
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var items = await RandomServiceExample.CallAsync("business");
}
Now let’s complicate a bit our items just like what we did with our Action callbacks earlier on:
Nothing new here, you’ll notice in the output console the item link show upon each task completion one by one.
How do we parallelize all of this just like it was with our usual action/callbacks?
var items = await RandomServiceExample.CallAsync("business");
if (items != null)
{
List<Task> tasks = new List<Task>();
foreach (var it in items)
{
WebClient client = new WebClient();
tasks.Add(client.DownloadStringTaskAsync(new Uri(it.Link, UriKind.Absolute)).ContinueWith(handleError));
}
TaskEx.WhenAll(tasks.ToArray());
}
Now to return to one of the points invoked earlier.. how DO I KNOW when all my clients have finished downloading? (yes RX is a solution I saw your grim
)
Yes you’ve guessed and you’re a pro by now: “await” keyword is also an answer.
var items = await RandomServiceExample.CallAsync("business");
if (items != null)
{
List<Task> tasks = new List<Task>();
foreach (var it in items)
{
WebClient client = new WebClient();
tasks.Add(client.DownloadStringTaskAsync(new Uri(it.Link, UriKind.Absolute)));
}
await TaskEx.WhenAll(tasks.ToArray());
Debug.WriteLine("finished everything ! wohoo!");
}
Bonus Tip:
I really like the “ContinueWith” method of a task, so let’s say your task is done and you wanted to check for exceptions and add these exceptions or track stuff, this is a cool way to do it.
Quick Example:
List<Exception> lstExceptions = new List<Exception>();
Action<Task<string>> handleError = new Action<Task<string>>((task) =>
{
if (task.Exception != null)
lstExceptions.Add(task.Exception);
});
var items = await RandomServiceExample.CallAsync("business");
if (items != null)
{
List<Task> tasks = new List<Task>();
foreach (var it in items)
{
WebClient client = new WebClient();
tasks.Add(client.DownloadStringTaskAsync(new Uri(it.Link, UriKind.Absolute)).ContinueWith(handleError));
}
await TaskEx.WhenAll(tasks.ToArray());
Debug.WriteLine("finished everything ! wohoo!");
}
Upon completing a task, handleError is called in which there’s a small exception test which would lead to adding the exception to a list of exceptions.
A few other tips:
- In order to use the “await” keyword, the task at hand should be “awaitable” – we’ll leave this to another article!
- HttpWebRequest also comes with async task helpers through methods like: GetResponseAsync & GetRequestStreamAsync .
- If you want to create your own async task, its duable with TaskEx.Run – also for another article!
So that’s it..
Hope you liked it, any feedback / additions which would help improve this article are welcome!

