Невозможно разорвать цикл с семафором

Я пытаюсь добавить список асинхронных задач при использовании .

       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)
    }
}

И в промежутке, если я вернусь, я хочу разорвать цикл и обработать. Для этого я использую cancelспособ отменить DispatchWorkItemно это не разрывает петлю.

      @IBAction func backWasPressed(_ sender: Any) {
    workItem?.cancel()
    navigationController?.popViewController(animated: true)
}

Любое решение, чтобы разорвать цикл и процесс semaphoreкогда я нажал кнопку назад?

2 ответа

Отменить его из основного потока

      DispatchQueue.main.async {
   workItem?.cancel()
   workItem = nil
}

В документации DispatchWorkItem сказано, что:

Отмена не влияет на выполнение рабочего элемента, который уже начался.

Поскольку ваш рабочий элемент уже начал выполняться, вам нужно найти другой обходной путь, чтобы отменить эту работу. В качестве альтернативы вы можете использовать отдельный поток , поскольку он соответствует вашим потребностям, поскольку у него есть эффективная поддержка отмены.

Другие вопросы по тегам