gpt4 book ai didi

ios - 队列何时会认为任务已完成?

转载 作者:行者123 更新时间:2023-12-03 22:59:43 25 4
gpt4 key购买 nike

在下面的代码中,queueT (串行队列)考虑“任务A”完成了吗?
瞬间aNetworkRequest 切换到另一个线程?
或在 doneInAnotherQueue堵塞? (评论//1)
换句话说,“任务 B”什么时候执行?

let queueT = DispatchQueue(label: "com.test.a")
queueT.async { // task A
aNetworkRequest.doneInAnotherQueue() { // completed in another thread possibly
// 1
}
}

queueT.async { // task B
print("It's my turn")
}
如果您可以解释队列如何认为任务完成的机制会更好。
提前致谢。

最佳答案

简而言之,第一个例子启动了一个异步网络请求,所以 async提交网络请求后立即调用“完成”(但不等待该网络请求完成)。
我假设真正的问题是您想知道网络请求何时完成。归根结底,GCD 不太适合管理任务之间的依赖关系,这些任务本身就是异步请求。将网络请求的发起分派(dispatch)到串行队列无疑不会达到您想要的效果。 (在有人建议使用信号量或调度组到 wait 以完成异步请求之前,请注意这可以解决战术问题,但这是一种需要避免的模式,因为它对资源的使用效率低,并且在边缘情况下,可能会引入死锁。)
一种模式是使用完成处理程序:

func performRequestA(completion: @escaping () -> Void) { // task A
aNetworkRequest.doneInAnotherQueue() { object in
...
completion()
}
}
现在,在实践中,我们通常会使用带有参数的完成处理程序,甚至可能是 Result。类型:
func performRequestA(completion: @escaping (Result<Foo, Error>) -> Void) { // task A
aNetworkRequest.doneInAnotherQueue() { result in
guard ... else {
completion(.failure(error))
return
}
let foo = ...
completion(.success(foo))
}
}
然后,您可以使用完成处理程序模式来处理结果、更新模型,并可能启动依赖于此请求结果的后续请求。例如:
performRequestA { result in
switch result {
case .failure(let error):
print(error)

case .success(let foo):
// update models or initiate next step in the process here
}
}

如果您真的想问如何管理异步任务之间的依赖关系,还有许多其他优雅的模式(例如,Combine、自定义异步 Operation 子类、即将推出的 SE-0296SE-0303 中设想的 async/await 模式, ETC。)。所有这些都是用于管理异步任务之间的依赖关系、控制并发程度等的优雅解决方案。
在我们提出任何具体建议之前,我们可能需要更好地了解您更广泛需求的性质。您已经问过有关单个调度的问题,但最好从您要实现的目标的更广泛的背景下看待这个问题。例如,我假设您在问,因为您有多个异步请求要启动:您真的需要确保它们按顺序发生并失去并发的所有性能优势吗?或者您是否可以允许它们同时运行,您只需要知道所有并发请求何时完成以及如何以正确的顺序获得结果?您是否有太多并发请求,您可能需要限制并发程度?
这些问题的答案可能会影响我们对如何最好地管理多个异步请求的建议。但答案几乎可以肯定不是 GCD 队列。

关于ios - 队列何时会认为任务已完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66851672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com