I'm trying to run multiple tasks on the main queue, some more urgent than others. I'm using DispatchQoS to do this:
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)
}
}
I expected to see five zeros, followed by five -1's, followed by five -2's, and so on.
But I got:
-15 -14 -13 -12 -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 -12 -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 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
In other words, the dispatch queue is executing tasks in the order they're enqueued, ignoring priority.
I then tried different QoS classes instead of different 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)
}
But the tasks again executed in the order of enqueueing, ignoring QoS.
How do I get the dispatch queue to respect QoS? My goal is to run some tasks on the main queue at a lower priority than others.
The solution turned out to be to use OperationQueue:
Then I can continually execute low priority tasks, one after another, without making the UI unresponsive.
Thanks to Rob for pointing out why DispatchQueues weren't respecting priorities.