I want to download some files, for example 100 files, at the same time. So I decided to add my download threads to a dispatch queue, and GCD will adjust how many threads will run at the same time.
The problem here is: the block in dispatch_async
will be completed immediately, because task
will run on another thread. So, if urls
's length is 100, it will create 100 threads immediately.
var queueDownloadTask = dispatch_queue_create("downloadQueue", nil)
for url in urls {
dispatch_async(queueDownloadTask) {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let fileTransferSession = NSURLSession(configuration: config)
let task = fileTransferSession.downloadTaskWithURL(url, completionHandler: { (responseUrl, response, error) -> Void in
println("completed")
})
task.resume()
}
}
How can I configure the block in dispatch_async
to wait for the download task to complete? I don't want use dispatch_semaphore
, because it only allow run one download task at the same time.
In Swift 4,
func executeMultiTask() {
//1. Create group
let taskGroup = DispatchGroup()
//2. Enter group
taskGroup.enter()
myTask1.execute(completeHandler: {
// ...
//3. Leave group
taskGroup.leave() //< balance with taskGroup.enter()
})
/* Add more tasks ...
//2. Enter group
taskGroup.enter()
myTask2.execute(completeHandler: {
//3. Leave group
defer {
// Use `defer` to make sure, `leave()` calls are balanced with `enter()`.
taskGroup.leave()
}
// ... more
})
*/
//4. Notify when all task completed at main thread queue.
taskGroup.notify(queue: .main) {
// All tasks are done.
// ...
}
}