The C# team posts answers to common questions and describes new language features
Today we announced the Visual Studio Async CTP, which shows one of the major features we plan to include in a future release of C# and Visual Basic. This feature makes development of asynchronous applications--which include everything from desktop applications with responsive UI to sophisticated web applications--much easier.
The future release will introduce two new keywords to the C# language: await and async. The await keyword is used to mark asynchronous calls, so that you don’t need to create callback functions anymore and can write code in the same way as if it were synchronous. The compiler will do all of the heavy lifting for you. The async keyword must be presented in the signature of the method that makes asynchronous calls. Briefly, you can use the await keyword only if the async keyword is in the method signature. The same is true for lambda expressions.
This post presents just a short description of the feature. I strongly recommend that you visit the Visual Studio Async CTP page to learn more of the details and get tons of useful resources, including the language spec and cool samples.
Although we have plenty of examples and resources available, it’s never enough. So I’m giving you one more demonstration of how much easier it might be to create asynchronous programs with a future version of the C# and Visual Basic languages.
First, some preparatory steps to make the example work:
The FacebookAsync application I want to show you downloads a list of friends from Facebook and displays their names and Facebook IDs. It has a button and a DataGrid control that autogenerates columns. Here is its XAML.
To get a list of friends, an application needs to perform several steps (according to Facebook Graph API), including making two asynchronous calls:
The full code of the version that doesn’t use the new async feature might look like this.
This is what you typically see when you have to deal with asynchronous applications: lots of callbacks, and overall the code is rather hard to read, although I spent some time on beautifying it. Now, let’s see how much easier it might be with the new async feature.
XAML will not change. The same is true for the FacebookFriend class, the button’s event handler, and all the properties in the MainPage class.
The changes start, unsurprisingly, in the GetFriends method. I’m going to make asynchronous calls by using the await keyword. But to enable this, I have to add the async keyword to the method signature.
Now I can start changing the code within the method. Let’s take a look at the existing code:
Instead of making a callback, you can get the result string by using the await keyword.
Note that I used a different method here: DownloadStringTaskAsync. This method doesn’t exist in Silverlight today; it’s a part of the CTP release only. In addition to new keywords in the C# and Visual Basic languages, future versions of the .NET Framework and Silverlight need to implement the Task-based Asynchronous Pattern (TAP). The details about this pattern are also included into the CTP release; look for “The Task-based Asynchronous Pattern” document.
According to this pattern, asynchronous methods should follow a certain naming convention: They should have the “Async” postfix (or “TaskAsync” if a method with the “Async” postfix already exists in the given API, as with the WebClient class). Such methods return instances of the Task or Task<TResult> class from the Task Parallel Library. But once again, the compiler does some work for you when you use the await keyword. In my example, the type of the token variable is not Task<String>, but just String; no extra work such as conversion or type casting is necessary.
And now you can simply continue writing your application logic in the same method! Everything I had in the OnDownloadCompleted_Token method can be moved to the GetFriends method. I don’t even need to create a new WebClient, since I already have one.
So, the code
from the OnDownloadCompleted_Token() method can be replaced with the following code (once again, using the new await keyword) and moved to the GetFriends method.
After that I can simply delete the OnDownloadCompleted_Token method. In fact, I can make everything even shorter. I don’t need to create the token variable, because I can use the await keyword right in the method call, like this:
The last step is to simply move the code from the OnDownloadCompleted_Friends method to the GetFriends method and delete the OnDownloadCompleted_Friends method.
Here’s what the final version of the GetFriends method looks like:
Instead of three methods I have just one, and it’s much more straightforward and easier to read. It simply has less code to begin with. I hope that I gave you just enough information to encourage you to explore more on your own and read more about the Visual Studio Async CTP.
> var facebookAuthUri = new StringBuilder(@"graph.facebook.com/.../authorize);
This is an anti-pattern in c# - the much clearer string+ operator will compile into code that's just as efficient. (of course, string.format() would be the clearest.)
What about thread affinity and sync context issues - we can guess if it's like f#, but could explain.
I've just heard about the await keyword and this was the first blog entry I read when trying to understand it. What I don't understand, however, is how is this different to doing things synchronously?
The example looks like a lot of syntax for turning an asynchronous call into a synchronous one, since it won't continue until the web method returns. Isn't this what we're trying to avoid?
Ah, await works like yield. Got it
I get 90% of what is going on here...
GetFriends() is essentially running in the original thread... at least until the first await is called, because then it returns Task. Then it continues in a call back. Now, isn't the callback essentially asynchronous?
Eventually "searchResults" is modified, which something in the display has to be looking at... How does this synchronize? Does the caller have to check to see if GetFriends() has completed and then refresh the display?
I think the point is that since the GetFriends method is marked as async, the Page_Load will return immediately (thus allowing the page to render).
Then once the GetFriends method has completed it will asynchronously update the friends list.
I guess the benefit of these keywords is it allows you to work in an almost synchronous way, thus simplifying your code.
That's what I was saying wasn't being explained in this case. There are gobs of articles on F# async, so that's a good place to look. Basically, during the await, your thread not block as it would be in a sync call, but is off doing other things, like handling other Task<>s or servicing your application message pump, etc. What needs to be explained is interaction with the GUI thread and the sync context - you need to know if (assuming a gui app) you are (still) on the GUI thread after the async so that you can interact w/the GUI w/o a Control.Invoke (winforms) or SyncContext.Post (wpf).
OK, I see my mistake. Honestly, I didn't expect that this will be the FIRST entry you ever read about the C# async feature. This post simply provides one more example and doesn't focus on explanations too much. I expected people to come from the CTP page, but the post got very high in search results (and I thought that there was no such a thing as too much SEO :-))
I don't want to repeat or copy-paste the info we already have available in other places. Once again, I'd encourage everybody to visit the official CTP page: msdn.microsoft.com/.../async.aspx
And download the whitepaper here: www.microsoft.com/.../confirmation.aspx
If it's still not enough, look at the C# language spec and Task-Asynchronous-Pattern (TAP) spec. They have all the implementation details.
Please please please make this feature work on all platforms, including Silverlight and Windows Phone 7 apps. Not sure if TPL is supported on Windows Phone, but it would be a shame for a language feature to work only on certain platforms and not others. <TwoCents/>
the Visual Studio Async CTP works only with US-version of VisualStudio 2010. Is there any intention to release a language-free version next time? On German VisualStudio 2010 is doesn't work.
Right now TPL is not supported in SIlverlight, you are right. But as you can see from the samples, Silverlight is definitely one of the areas where we'd like to see it work.
Unfortunately, this is a known issue and there is no fix for it. This CTP version works only with en-us version of Visual Studio 2010
For async enumeration, is the standard way going to be an IEnumerable<Task<T>>? Or will you be introducing a more preferable IAsyncEnumerator<T> with a Task-returning MoveNext? Could open up some interesting patterns like "foreach(await var x in asyncenumerable)".
Why just not providing a dynamic parser, one where syntax can be extended like in Boo? This async thing could be simply resolved by using that.
It seems to me that a dynamic parser is the natural step after dynamic languages.
Is this feature similar to node.js asynchronous programming model ?
Hi I downloaded Visual Studio Async CTP but I get this error during installation:
Could not load type "System.Windows.Input.FocusNavigationDirection" from assembly 'WindowsBase, Version=188.8.131.52, culture=neutral, PublicKeyToken=31bf3856ad36e35' due to value type mismatch.
Then when I try to open VS 2010 I get the same error and VS is closed automatically.
The funnies thing is the installation finished with a "Successfully message" and the installation log file is the same,
I looked to my GAC and WindowsBase assembly existing but version 184.108.40.206, I believe this is the problem, it looks like this CTP is looking for version 4, Am I correct ?
Thanks for your help
All the await statement does is execute the Task in a different thread and allows the current thread to continue, until such time the Task is complete, and then the next statement available after the await statement is called and execution continues in that stack, once the stack is complete the current thread then continues its execution from where it was before the Task completed.
There is really nothing magical going on here, except for the automatic ability for the statements after the await statement to be called once the task is completed, otherwise this would normally have to be done using a delegate callback or an event.