问题描述:
我想通过'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
}
如果发生超时,如何获得最新结果?
答案 0 :(得分:0)
好的,因此您可以正确使用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()
}
}
}
}
这个简单的函数在全局后台队列上异步调度,然后调用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()
}
}
然后使用我们的新功能等待结束
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
}