DispatchWorkItem не завершает функцию при вызове .cancel () - PullRequest
0 голосов
/ 03 октября 2018

У меня есть серия HTTP-запросов, выполняемых последовательно с использованием Alamofire в списке функций, вызываемых в основной функции, runTask(), которые я хочу иметь возможность остановить.Итак, я настроил вызов функции runTask() в DispatchWorkItem для каждой задачи, которую мне нужно запустить, и сохранил рабочий элемент в массиве так:

taskWorkItems.append(DispatchWorkItem { [weak self] in
    concurrentQueue!.async {
        runTask(task: task)
    }
})

Затем я повторяюмассив рабочих элементов и вызвать функцию perform() следующим образом:

for workItem in taskWorkItems {
    workItem.perform()
}

Наконец, у меня в приложении есть кнопка, которую я хочу отменить рабочие элементы при нажатии, и у меня есть следующий кодчтобы это произошло:

for workItem in taskWorkItems {
    concurrentQueue!.async {
        workItem.cancel()

        print(workItem.isCancelled)
    }
}

workItem.isCancelled печатает до true;тем не менее, у меня есть журналы, настроенные в функциях, вызываемых runTask(), и я все еще вижу функции, выполняющиеся, даже если вызван workItem.cancel() и workItem.isCancelled печатает true.Что я делаю неправильно и как я могу остановить выполнение своих функций?

1 Ответ

0 голосов
/ 03 октября 2018

TLDR: вызов отмены остановит выполнение задач, если они еще не запущены, но не остановит выполнение того, что уже выполняется.

Поскольку документы Apple на этом являются изношенными ...

https://medium.com/@yostane/swift-sweet-bits-the-dispatch-framework-ios-10-e34451d59a86

A dispatch work item has a cancel flag. If it is cancelled before running, the dispatch queue won’t execute it and will skip it. If it is cancelled during its execution, the cancel property return True. In that case, we can abort the execution

//create the dispatch work item
var dwi2:DispatchWorkItem?
dwi2 = DispatchWorkItem {
    for i in 1...5 {
        print("\(dwi2?.isCancelled)")
        if (dwi2?.isCancelled)!{
            break
        }
        sleep(1)
        print("DispatchWorkItem 2: \(i)")
    }
}
//submit the work item to the default global queue
DispatchQueue.global().async(execute: dwi2!)

//cancelling the task after 3 seconds
DispatchQueue.global().async{
    sleep(3)
    dwi2?.cancel()
}
...