我试图在主队列上运行多个任务,有些任务比其他任务更紧急。我正在使用DispatchQoS来完成以下操作:
func enqueue(_ prio: Int) {
let qos = DispatchQoS(qosClass: .userInteractive, relativePriority: prio)
DispatchQueue.main.async(qos: qos) {
NSLog("\(prio)")
}
}
for i in 1...5 {
for prio in -15...0 {
enqueue(prio)
}
}我希望看到5个0,然后是5-1,然后是5-2,等等。
但我得到了:
-15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -0 -15 -14 -13 -12 -11 -10 -9 -8 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
换句话说,调度队列按照任务的排队顺序执行任务,忽略优先级。
然后,我尝试了不同的QoS类而不是不同的relativePriority:
func enqueue(_ qos: DispatchQoS) {
DispatchQueue.main.async(qos: qos) {
NSLog("\(qos.qosClass)")
}
}
for i in 1...10 {
enqueue(.background)
enqueue(.utility)
enqueue(.userInitiated)
enqueue(.userInteractive)
}但是任务再次按照排队的顺序执行,忽略了QoS。
如何使调度队列尊重QoS?我的目标是在主队列上以比其他任务更低的优先级运行一些任务。
发布于 2017-09-18 06:45:12
最终的解决方案是使用OperationQueue:
let operation = BlockOperation(block: self.doSomething)
operation.queuePriority = .low
OperationQueue.main.addOperation(operation)然后,我可以一个接一个地执行低优先级的任务,而不会使UI没有响应性。
感谢罗伯指出了为什么DispatchQueues不尊重优先级。
发布于 2017-09-08 07:22:38
在WWDC 2016视频Swift 3中的GCD并发编程中,他们提到,当您向具有较高优先级的队列中添加某些内容时,它不会“跳出队列”,而是使用QoS来解决优先级倒置(例如,它可以使用它来增加队列中先前任务的优先级,以满足高优先级的后续任务,而不是改变串行队列中任务的顺序)。
另外,我建议你不要在主队列中测试这类东西。这是一个带有专用线程的特殊串行队列,因此它对于检查QoS如何影响任务的调度和优先级并不十分有用。我建议为测试QoS问题创建自己的并发队列。此外,如果将任务添加到并发队列中,它们通常必须足够实质性和足够多,才能看到任何可识别的模式。
最后,我鼓励你观看2015年用GCD构建响应高效的应用程序视频,因为它更详细地进入了QoS。上述2016年视频有利于Swift 3的具体观测,但它实际上是建立在2015年视频的QoS讨论的基础上。
https://stackoverflow.com/questions/46109945
复制相似问题