I am trying to add a list of async tasks in DispatchWorkItem
using semaphore
.
func performStickerWorkItems(_ stickers: [String]) {
let queue = DispatchQueue.global(qos: .background)
workItem = DispatchWorkItem { [weak self] in
for sticker in stickers {
guard let item = self?.workItem, !item.isCancelled else {
print("cancelled")
break
}
let semaphore = DispatchSemaphore(value: 0)
self?.addSticker(sticker: sticker) {
print("S: \(sticker)")
semaphore.signal()
}
semaphore.wait()
}
self?.workItem = nil
}
queue.async(execute: workItem!)
workItem?.notify(queue: .main) {
self.updateButton(false)
}
}
And in between if I go back, I want it to break the loop and process. For that, I use the cancel
method to cancel DispatchWorkItem
but it doesn't break the loop.
@IBAction func backWasPressed(_ sender: Any) {
workItem?.cancel()
navigationController?.popViewController(animated: true)
}
Any solution to break the loop and process of semaphore
when I pressed the back button?
CodePudding user response:
Cancel it from main thread
DispatchQueue.main.async {
workItem?.cancel()
}
CodePudding user response:
In the DispatchWorkItem documentation says that:
Cancellation does not affect the execution of a work item that has already begun.
Since your work item has already begun to execution, you need to find out another workaround to cancel that work. You can alternatively use a separate Thread since it conforms your need because it does have an effective cancellation support.