Introduction
New C# programming feature announcements are always big news. Microsoft recently announced new C# programming features for making asynchronous programming easier. This is good for developer’s building applications requiring asynchronous programming, but why venture into asynchronous code if it’s not required? The short answer is application users are always looking for a better experience. Look to the adoption of the Graphical User Interface and increasingly more powerful mobile applications for examples of tech savvy consumers demanding a better experience.
Make the skills involved in creating a new user experience more accessible to the average developer and every developer starts incorporating the new user experience into their application. Eventually the new experience is common and not long afterward the new experience becomes a necessity. By making asynchronous coding easier, will this new language feature turn the application responsiveness developers get with asynchronous code into a needed experience?
To help answer that question, using sample code from the “Async CTP”, I’m going to walk through the new asynchronous development experience and contrast the development experience with asynchronous code and synchronous code written using current techniques. I’ll start with an overview of the sample code.
Sample Overview
Improved User Interface responsiveness is the canonical business case for employing asynchronous code. You’ll find the source code for the “Netflix” sample among the resources at the end of the article. As I mentioned earlier this is a Community Technology Preview (CTP). Like all CTPs and Betas, unless explicitly stated, the underlying implementations are subject to change.
A graphic of the sample in action appears below.
[Demo.gif]
Figure 1 Sample in action
As you can see a user enters a year and the application displays all the movies of that year. The code is divided into three samples:
- A sample developed using the synchronous experience.
- An asynchronous sample developed using delegates (Actions).
- An asynchronous sample developed using the new Async features.
As stated earlier, I’ll walk through each sample comparing and contrasting the synchronous, current asynchronous and new asynchronous development experience.
Synchronous
The code from the synchronous sample appears below.
void LoadMovies(int year) { resultsPanel.Children.Clear(); cts = new CancellationTokenSource(); statusText.Text = ""; var pageSize = 10; var imageCount = 0; try { while (true) { statusText.Text = string.Format("Searching... {0} Titles", imageCount); // (status text doesn't work because the UI never has a breather to show it) var movies = QueryMovies(year, imageCount, pageSize, cts.Token); if (movies.Length == 0) break; DisplayMovies(movies); imageCount += movies.Length; } statusText.Text = string.Format("{0} Titles", imageCount); } catch (TaskCanceledException) { } cts = null; } Movie[] QueryMovies(int year, int first, int count, CancellationToken ct) { var client = new WebClient(); var url = String.Format(query, year, first, count); var data = client.DownloadString(new Uri(url)); var movies = from entry in XDocument.Parse(data).Descendants(xa + "entry") let properties = entry.Element(xm + "properties") select new Movie { Title = (string)entry.Element(xa + "title"), Url = (string)properties.Element(xd + "Url"), BoxArtUrl = (string)properties.Element(xd + "BoxArt").Element(xd + "LargeUrl") }; return movies.ToArray(); }
The code above works like you would expect. LoadMovies
is the main body of the collection process. Using the WebClient
class QueryMovies
gathers the movie information into one large XML string, parses the string and creates an array of Movie classes. DisplayMovies
renders Bitmaps from the URLs stored in the array of Movie classes.
If you run the synchronous sample, it won’t take long before you want to simply cancel it and move on to running the other samples.
Far more performant code can be written using asynchronous functions. As stated earlier the first asynchronous sample is written with delegates.