You may have seen this piece I wrote about implementing something like C#’s async/await in Swift. While that code did work, it suffers from a couple of problems relative to what’s available in C#. The first problem is that it only supports a single return type, Int
, because of a problem with the current version of the Swift compiler.
The second problem is that you can’t use it from the main thread in a Cocoa or Cocoa Touch program, because await
blocks.
As I mentioned previously on Twitter, to make it work really well involves some shennanigans with the stack. Anyway, I’m pleased to announce that I’ve been merrily hacking away and as a result you can download a small framework project that implements async/await from BitBucket.
I’m quite pleased with the syntax I’ve managed to construct for this as well; it looks almost as if it’s a native language feature:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Now, to date I haven’t actually tried it on iOS; I think it should work, but it’s possible that it will crash horribly. It is certainly working on OS X, though.
How does it work? Well, behind the scenes, when you use the async
function, a new (very small) stack is created for your code to run in. The C code then uses _setjmp()
and _longjmp()
to switch between different contexts when necessary. If you want to cringe slightly now, be my guest :-)
Possible improvements when I get the time:
- Reduce the cost of async invocation by caching async context stacks
- Once Swift is fixed, remove the
T[]
hack that we’re using instead of declaring the result type in theTask<T>
object asT?
. The latter presently doesn’t work because of a compiler limitation.