As many of you will have seen yesterday, the major new feature of C# 5 was announced yesterday: support for asynchronous operations with new contextual keywords of "async" and "await". I haven’t had a lot of time to play with them yet, but I have a few initial thoughts. Note that these won’t make any sense to you unless you’ve also watched the talk Anders gave, or read Eric’s blog post, or something similar. Links are at the bottom of this post rather than peppered throughout.
Asynchronous != parallel
Do you remember when LINQ was first announced, and there was a huge fear that it was effectively putting SQL into C#, when in fact the truth was more general? Well, it’s the same here. The language feature allows a method to execute asynchronously, but it won’t create new threads and the like automatically.
I suspect there’s going to be a lot of confusion about which parts of the asynchronous model are provided by the language and which by the framework. Obviously I’ll hope to clarify things where I can, but it’s important to understand that the language isn’t going to automatically start extra threads or anything like that.
In the Channel9 PDC interview, Anders stressed this point pretty hard – which suggests he thinks it’s going to cause confusion too. I became a lot more comfortable with what’s going on after reading the draft spec – which is part of the CTP.
Language and framework interaction
It looks like the language changes have been designed to be pattern-based, a little like LINQ and foreach. The async modifier is present more for the sake of developers than the compiler, and the await contextual keyword simply requires a
GetAwaiter() method to be available (which can be an extension method); that method has to return something for which
EndAwait() are valid – and again, these can be extension methods.
One of the tests I performed yesterday was to try to use this myself, with a custom "awaiter factory" – it worked fine, and it’s definitely an interesting way of exploring what’s going on. Expect a blog post along those lines some time next week.
So far, so framework-neutral… the only slight fly in the ointment is the reliance on
Task<T>. Just as an iterator block with
yield return 10; would usually be declared to return
IEnumerable<int>, so an async method ending in
return 10; would have a return type of
Task<int>. I don’t think that’s actually too bad – but I’ll have to dig into exactly what the language relies on to be completely comfortable with. Are there any aspects of tasks which are usually configured by their factories, for example? If so, what does the compiler do?
My gut feeling is that the language is still keeping the framework at an appropriate distance as far as it can, but that it’s got to have something like
Task<T> as a way of representing an asynchronous operation.
But is it any use?
Again, I’m really going on gut feelings so far. I think it’s going to be very useful – and I wish I had something similar in Java when writing internal services at work. I like the fact that it’s relatively simple – it feels much simpler than dynamic typing, for example – so I think I’ll be able to get my head round it.
It’s important to note that it’s not a free lunch, and doesn’t try to be. It removes much of the error-prone mechanical drudgery of writing asynchronous code, but it doesn’t attempt to magically parallelize everything you do. You still need to think about what makes sense to do asynchronously, and how to introduce parallelism where appropriate. That’s a really good thing, in my view: it’s about managing complexity rather than hiding it.
I think C# 5 is going to be a lot of fun… but I also think you’re going to need to understand the Task Parallel Library to really make the most of it. Keep the two separate in your head, and understand how they complement each other. If ever there was a good time to learn TPL thoroughly, it’s now. Learning the C# 5 features themselves won’t take long. Mastering the combination of the two in a practical way could be a much bigger task.
Obviously there are lots of resources flooding out of Microsoft (and other bloggers) at the moment. Here are a few to start with:
- The Visual Studio async home – probably the best site to bookmark, as I’m sure it’ll get updated over time. Download the CTP from here, as well as watching various videos.
- PDC 2010 player – as this was announced at PDC, there are lots of talks there, including the session where Anders introduces the feature.
- Eric Lippert’s first blog post on async – with more to come, of course. Follow the Async or C# 5.0 tags.
- A blog post by Michael Crump with a CTP walkthrough