簡體   English   中英

如何停止DispatchGroup或OperationQueue等待?

[英]How to stop DispatchGroup or OperationQueue waiting?

DispatchGroupOperationQueue具有方法wait()waitUntilAllOperationsAreFinished() ,它們等待相應隊列中的所有操作完成。

但是,即使我調用cancelAllOperations它也只是在每個正在運行的操作中更改了isCancelled標志,並停止了執行新操作的隊列。 但是它仍然等待操作完成。 因此,必須從內部停止運行操作。 但是只有在操作是增量的或具有任何內部循環的情況下才有可能。 當只是長時間的外部請求(例如Web請求)時,不使用isCancelled變量。

如果其中一項操作確定所有隊列現在都已過時,是否有任何方法可以停止OperationQueue或DispatchGroup等待操作完成?

實際情況是:將請求映射到響應者列表,並且已知只有一個人可以回答。 如果發生這種情況,隊列應停止等待其他操作完成並解鎖線程。

編輯:DispatchGroup和OperationQueue的使用不是強制性的,這些只是我認為合適的工具。

好,所以我想出了點什么。 結果很穩定,我剛剛測試過。 答案只是一個信號量:)

let semaphore = DispatchSemaphore(value: 0)
let group = DispatchGroup()
let queue = DispatchQueue(label: "map-reduce", qos: .userInitiated, attributes: .concurrent)
let stopAtFirst = true // false for all results to be appended into one array
let values: [U] = <some input values>
let mapper: (U) throws -> T? = <closure>
var result: [T?] = []
for value in values {
    queue.async(group: group) {
        do {
            let res = try mapper(value)
            // appending must always be thread-safe, otherwise you end up with race condition and unstable results
            DispatchQueue.global().sync {
                result.append(res)
            }
            if stopAtFirst && res != nil {
                semaphore.signal()
            }
        } catch let error {
            print("Could not map value \"\(value)\" to mapper \(mapper): \(error)")
        }
    }
}
group.notify(queue: queue) { // this must be declared exactly after submitting all tasks, otherwise notification fires instantly
    semaphore.signal()
}
if semaphore.wait(timeout: .init(secondsFromNow: 5)) == .timedOut {
    print("MapReduce timed out on values \(values)")
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM