Today I’d like to say happy birthday to the C#
await keywords! They officially turn five years old today! C# and VB both officially adopted them on September 12, 2012.
await keywords themselves have a slightly longer history; they were originally introduced in F# on April 12th, 2010.
async; the Python community is quick to pick up (or invent) the best language features, and they have one of the best language-improvement processes out there. Also, I find the Hack adoption particularly amusing - I mean, even PHP has
async these days!
The jury is still out on whether C++ will pick up
async, and Java just seems to move at a snail’s pace these days.
Remembering Ye Olde Async Days
My original intro to
await post went live on my blog about five and a half years ago! It’s still fully relevant, which is unusual for a five-year-old blog post. And even today, it brings more traffic to my blog than any other post (about 15% of all my blog traffic is just for that one post).
My, how much has changed since that blog post was published! At that time,
async was an experimental language modification that required you to install a Community Technology Preview (read: unsupported) package that changed the compilers and language features used by Visual Studio 2010. That is, unless you already installed updates to VS2010, in which case the Async CTP installation would just not work. Until they fixed it, and then it worked. Until the next VS2010 update, when it broke again. No, seriously, it was that bad! :)
Oh, and once (if) you managed to get the Async CTP installed, there were still a number of bugs. And if you encountered them, there wasn’t much you could do about it: the resolution was essentially “don’t do that.” Of particular note was using multiple
awaits in expressions, like Lucian’s example
var x = await f() + await g(); Yeah, that didn’t even work. Your rule-of-thumb was one
await per statement, and it was best if that statement did nothing else.
var fx = await f(); var gx = await g(); var x = fx + gx; FTW!
Also, overload resolution wasn’t quite right, especially for asynchronous delegate types. But there were no
async lambdas anyway. And there was no
dynamic compatibility with
await at all. And a lot of compiler safeguards were missing (e.g.,
async void Main was allowed). And the debugger support was horrible - really, there was no debugging support at all back then.
async is truly a first-class citizen of C# and VB. With every release of Visual Studio, the debugger support for
async code gets better and better. Tracing systems like Application Insights “just work” coordinating traces across asynchronous code. We recently got value-type
Task<T> equivalents, and new enhancements are on the horizon: better code generation around the
async state machine,
async enumerators, … the future is bright!