Overview
Atlassian Sourcetree is a free Git and Mercurial client for Windows.
Atlassian Sourcetree is a free Git and Mercurial client for Mac.
Async Swift
This framework implements C#-like async/await primitives in Swift. Owing tosome problems with the current operating system bindings, together with theneed for a tiny bit of assembly language to make this work, the guts of theimplementation are currently written in C.
The implementation could be adapted to work with Objective-C or C++ in arelatively straightforward manner.
Usage
Basic usage is as follows:
let task = async { () -> Int in return 5}let result = await(task)Note that the type of the block isnot optional.
You can return any Swift object you like, and the result is returned fromtheawait call.
Obviously, it's permissible to invoke asynchronous tasks within asynchronoustasks, for instance
let task = async { () -> Int in let subtask = async { () -> Int in return 15 } return await(subtask) * 2}let result = await(task)Neither of these examples are particularly useful, so let’s give an examplethat is:
let task = async { () -> () in let fetch = async { (t: Task<NSData>) -> NSData in let req = NSURLRequest(URL: NSURL.URLWithString("http://www.google.com")) let queue = NSOperationQueue.mainQueue() var data = NSData! NSURLConnection.sendAsynchronousRequest(req, queue:queue, completionHandler:{ (r: NSURLResponse!, d: NSData!, error: NSError!) -> Void in data = d Async.wake(t) }) Async.suspend() return data! } let data = await(fetch) let str = NSString(bytes: data.bytes, length: data.length, encoding: NSUTF8StringEncoding) println(str)}You need to do a little set-up to make this work in your Cocoa/Cocoa Touchcode, namely at some point you need to bind the Async module to the run loopwith
Async.schedule(NSRunLoop.currentRunLoop())
After doing that, if you invoke the code above, you’ll find that it fetchesthe Google home page into a string, which is returned as the result oftask.
Note: Youmust not callawait directly from a non-async context in aCocoa program unless you arecertain the task in question has completed.Doing so will trigger an assertion failure.
await semantics
async andawait do not behave the way you might naïvely assume. If youcallawait (orAsync.suspend) in an async context,control will return tothe calling frame. It doesnot block. All that is suspended is executionwithin the async context.
The only time thatawait will block is if you are at the top level, outsideof any async context. In that case, it will block the top level (but willcontinue running any async code as it becomes ready) until the specified taskis complete.
If you're using this module in a Cocoa or Cocoa Touch program, and you want torun asynchronous code on the main thread, you can tell the framework that youwant it to attach to the run loop, as shown before, with
Async.schedule(NSRunLoop.currentRunLoop())
This also works forCFRunLoopRef, and it will work with the main dispatchqueue as well if your programs use those instead.
Once you have done that, async tasks that you start from event handlers (orfrom blocks dispatched by the main dispatch queue) will continue to run tocompletion automatically. The framework does this by scheduling callbacksfor itself in the run loop at appropriate times.
Async.suspend() andAsync.wake()
These two functions allow you to suspend the current async context, and towake a previously suspended context, respectively. They are used to interfaceasync code with code that uses other methods of asynchronous behaviour (e.g.threads, dispatch queues, callbacks, completion blocks and so on).
Waking is not instant; the context will resume from the point of theAsync.suspend call when either (a)await is called at top leveland hasto wait, or (b) your program returns to the run loop or dispatch queue withwhich theAsync module is scheduled.
Note that the order that suspended async contexts resume is not guaranteed.
Threading support
TheAsync module is designed to work with threads in the following manner;each thread has its own entirely separate pool of async contexts, and its owndistinct set of async tasks. Youmust not attempt toawait on a task thatis owned by another thread.
Important: dispatch queues other than the main queuedo not guaranteethat tasks will be invoked on the same thread. This applieseven to serialqueues, and is the reason that you must only ever pass the main dispatchqueue to theAsync.schedule function.
Itis safe to use async contexts within a block dispatched to a queue, butbear in mind that you cannotawait on a task from a different block, thoughit is certainly permissible to callAsync.wake on one.



