We’ve shipped the Async CTP! And VB also has iterators!
I’m writing this blog post at 8.30pm on the evening before the Async CTP will ship. We’re all pretty nervous and excited. Most of the Async/VB/C# team are at an “MVP Insiders” party. I’m sitting here fretting over code and writing tutorials.
Excited, and writing tutorials
I’ve been working on concurrency for my entire professional life, since graduating from college in 1995. And despite this background I have to say that the ideas in the Async CTP took me quite by surprise. The ideas came from F# Async Workflows and from the Axum prototype released by Microsoft last year, and we’ve developed them further to make them fit fluently into C# and VB.
Because the ideas are fairly new, there hasn’t been much academic literature on the subject, nor textbooks, nor training courses. We’re having to invent new concepts and patterns, and then figure out the most effective way to teach those concepts.
One of those surprising concepts is that asynchrony doesn’t mean “background thread”. Most people think it does! It’s a little cocky for us to come out and tell the world “you’ve been using the word ‘async’ wrongly all these years”, but that’s what we’re doing.
Async Function DoWork() As Task
‘ … CPU-bound work to compute fast fourier transforms
When people look at this code, about 80% will see the word Async and immediately assume that it’s going to run that work on a background thread. Those are the approximate results of our initial usability studies and internal testing. Of course, that’s not what it actually means. What it means is that the method might have Await expressions in it, and (if it does) then it might end up returning its resultant Task before the body of the method has actually completed. I’ll spell out our motives for co-opting the word “async” in a future post.
Another surprising concept is that of single-threaded concurrency. It shouldn’t have been so surprising, since people have been doing cooperative multitasking for decades — including in Windows 3.1 with the Yield keyword, and before that CallCC in Scheme and ML, and always with co-routines. But I think that the Await keyword makes cooperative multitasking more valuable now than it has been in the past. I’ll be writing more about why we like this approach (as compared to the “zillions of threads” approach of the Go language, for instance), in a future post.
Nervous, and fretting over code
We’ve spent the last week building an installer, testing it, signing it, and preparing release material.
Today (the day before we ship the CTP) we discovered a serious bug where VB’s XML-literals didn’t work in async or iterator methods, so I fixed the bug, hastily tested it, we scrapped the installer and started rebuilding it over from scratch. That process takes several hours and involves the cooperation and good will of many kind people in the company. The Async CTP touches about 5% of the .cpp and .h files that make up the C# and VB compilers. I wrote much of the CTP, and so feel personally responsible for every bug.
Now (the evening before we ship the CTP) I just discovered another serious bug where VB will crash if a variable’s type is inferred from an await expression and then you double-dot off it, e.g. “Dim result = Await t : result.Descendants.ToString()”. I’ve fixed the bug, and I have to figure out whether to drag people away from their party, start a rebuild of the installer, and jeopardize the timing of the release in case it doesn’t finish in time.
I think it’s not quite that serious: everyone can have their party and their sleep, and the fix can be left for an update in a few days’ time or maybe skipped entirely.
This Async CTP has been largely an “underground” project by a small group of 5 program-managers. Microsoft divides its employees into three categories: developers who write code, testers who test it, and program managers who look after specifications and deadlines. For most of the CTP’s development cycle, we five PMs had to fill all three roles to build something substantial enough that management would approve it. This meant many late nights — on some weeks sleeping more nights at the office than at home. What made all this effort worthwhile was the joy of working with such smart colleagues, and the satisfaction of finally being able to implement, refine and publish the answer that those smart colleagues delivered to the research question I first started asking in 1995: “how should you think about concurrency and make it usable for everyday programming?“