Skip to content

Instantly share code, notes, and snippets.

@werediver
Last active July 3, 2017 09:06
Show Gist options
  • Save werediver/a7cc14177f67e52ff67fbeaf37acb55c to your computer and use it in GitHub Desktop.
Save werediver/a7cc14177f67e52ff67fbeaf37acb55c to your computer and use it in GitHub Desktop.
Limiting concurrent tasks.
import Foundation
func dispatch_async_batch(tasks: [() -> ()], limit: Int, completion: (() -> ())?) {
if tasks.count > 0 || completion != nil {
let q = dispatch_queue_create("dispatch_async_batch", DISPATCH_QUEUE_CONCURRENT);
let sema = dispatch_semaphore_create(limit);
dispatch_async(q, {
for task in tasks {
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
dispatch_async(q, {
task() // The task must be synchronous!
dispatch_semaphore_signal(sema)
})
}
if let completion = completion {
dispatch_barrier_async(q, completion)
}
})
}
}
func dummy(t: NSTimeInterval, _ dt: NSTimeInterval) {
let _t = t + dt * (Double(arc4random()) / Double(UInt32.max) * 2 - 1)
NSThread.sleepForTimeInterval(_t)
}
let tasks = (0 ..< 12).map { i in
return {
print("+ Task #\(i) started")
dummy(4, 2)
print("- Task #\(i) stopped")
}
}
print("Scheduling \(tasks.count) task(s)...")
let sema = dispatch_semaphore_create(1)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
dispatch_async_batch(tasks, limit: 4) {
print("All tasks has been completed.")
dispatch_semaphore_signal(sema)
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) // Don't let the app terminate until the background work is finished.
/* Sample output
Scheduling 12 task(s)...
+ Task #0 started
+ Task #1 started
+ Task #2 started
+ Task #3 started
- Task #1 stopped
+ Task #4 started
- Task #0 stopped
+ Task #5 started
- Task #2 stopped
+ Task #6 started
- Task #3 stopped
+ Task #7 started
- Task #6 stopped
+ Task #8 started
- Task #4 stopped
+ Task #9 started
- Task #7 stopped
+ Task #10 started
- Task #5 stopped
+ Task #11 started
- Task #8 stopped
- Task #9 stopped
- Task #10 stopped
- Task #11 stopped
All tasks has been completed.
*/
@utdrmac
Copy link

utdrmac commented Nov 30, 2016

Do you have an update for this for Swift 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment