Soh*_*ard 2 grand-central-dispatch ios swift
问题描述:
我想通过“DispatchGroup”执行一堆异步任务,当所有任务完成时,它会返回结果。此外,我想设置限制过程的超时,并在那时向我发送回成功的结果。我使用了以下结构:
代码块
let myGroup = DispatchGroup()
var result = [Data]()
for i in 0 ..< 5 {
myGroup.enter()
Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in
print("Finished request \(i)")
result.append(response.data)
myGroup.leave()
}
}
// Timeout for 10 seconds
myGroup.wait(timeout: DispatchTime(uptimeNanoseconds: 10000000000))
myGroup.notify(queue: .main) {
return result
}
Run Code Online (Sandbox Code Playgroud)
如果超时如何获取最新结果?
好的,您正确使用了 的进入/离开功能DispatchGroup,但在如何访问这些结果方面遇到了困难。我认为尝试同时使用wait和会出错notify,这两个函数提供了通常不一起使用的两个不同的功能。设置好工作项目后,您有两个选择:
wait方法此函数会阻塞调用队列并同步等待传入的挂起时间过去或组中的所有工作项离开。由于它会阻塞调用者,因此在此函数中始终设置超时非常重要。
notify方法该函数采用一个目标队列和一个在组中的所有工作项完成后运行的块。在这里,您基本上是要求系统在所有工作项完成后异步通知您。由于这是异步的,我们通常不太担心超时,它不会阻塞任何东西。
wait(这似乎是你想要的?)如果像您所做的那样,我们希望在所有工作项目完成后收到通知,但也有超时,那么我们必须自己完成此操作,而且这并不是那么棘手。我们可以为该类添加一个简单的扩展DispatchGroup......
extension DispatchGroup {
func notifyWait(target: DispatchQueue, timeout: DispatchTime, handler: @escaping (() -> Void)) {
DispatchQueue.global(qos: .default).async {
_ = self.wait(timeout: timeout)
target.async {
handler()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个简单的函数在全局后台队列上异步分派,然后调用 wait,这将等待所有工作项完成或指定的超时,以先到者为准。然后它会回调指定队列上的处理程序。
这就是理论,你如何使用它。我们可以让您的初始设置完全相同
let myGroup = DispatchGroup()
var result = [Data]()
for i in 0 ..< 5 {
myGroup.enter()
Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in
print("Finished request \(i)")
result.append(response.data)
myGroup.leave()
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用我们的新函数等待结束
myGroup.notifyWait(target: .main,
timeout: DispatchTime.now() + 10) {
// here you can access the `results` list, with any data that has
// been appended by the work items above before the timeout
// was reached
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1792 次 |
| 最近记录: |