调度程序中的几个任务.他们会按顺序运行



在以下代码中,是否可以安全地附加到数组?保证维护订单吗?

let processedData: [SomeType] = []
let dispatchGroup = DispatchGroup()
for _ in 0..<N {
    dispatchGroup.enter()
    startSomeAsyncTaskXYZ { (data, error) in
        // handle error and process data
        // add processed data to an array
        processedData.append(..)
        dispatchGroup.leave()
    }
}
dispatchGroup.notify(queue: .main) {
    // update UI
}

在保留所需的异步性质和预期订购时坚持使用DispatchGroup,使您的数组成为一系列选项,并以任何顺序填充任务:

var processedData: [SomeType?] = Array(repeating: nil, count: N)
let dispatchGroup = DispatchGroup()
for idx in 0..<N {
    dispatchGroup.enter()
    startSomeAsyncTaskXYZ { (data, error) in
        // Ensure we always .leave() after we're done
        // handling the completion of the task
        defer { dispatchGroup.leave() }
        guard let data = data,
              error == nil else {
            // TODO: Actual error handling
            return
        }
        // This needs to be .sync now (not .async) to ensure
        // the deferred dispatchGroup.leave() is not called
        // until *after* we've updated the array
        DispatchQueue.main.sync {
            processedData[idx] = SomeType(data: data)
        }
    }
}
dispatchGroup.notify(queue: .main) {
    // update UI
}

DispatchGroup与执行顺序无关。这仅仅是跟踪任务组完成的一种方式。

该组的组成任务是否运行asyncsync,以及按什么顺序运行,完全取决于您如何使用DispatchQueues。

刚刚使用我的应用程序进行了此操作。我有一些需要按顺序完成的异步任务。完成此操作的最佳方法是通过dispatchGroup()semaphore()

基本思想是dispatchGroup没有以特定顺序获取数据,但是如果需要,semaphore的特定顺序是。

这是一个很好的视频,可以证明它:https://www.youtube.com/watch?v=6rjn_ecd1xm& ab_channel = letsbuildthatapp

一些示例代码看起来像这样:

let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
let dispatchGroup = DispatchGroup()
let semaphore = DispatchSemaphore(value: 0)
override func viewDidLoad() {
dispatchQueue.async {
        
        // --------------
        // Family members
        // --------------
        
        // Get members and household information first (esp. payday time and time zone), then everything else
        self.dispatchGroup.enter()
        MPUser.loadFamilyMembers {
            
            print("We got us some fambly members!")
            
            self.dispatchGroup.leave()
            self.semaphore.signal()
        }
        
        // ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first)
        self.semaphore.wait()
        // --------------
        // Household info
        // --------------
        self.dispatchGroup.enter()
        FamilyData.observeHouseholdInformation {
            self.dispatchGroup.leave()
            self.semaphore.signal()
        }
        // ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first, then household info)
        self.semaphore.wait()
        // ---------------
        // Everything else
        // ---------------
        self.dispatchGroup.enter()
        Setup.observeProgress {
            self.dispatchGroup.leave()
        }
        
        self.dispatchGroup.enter()
        OutsideIncome.observeUserOutsideIncomeBudget {
            self.dispatchGroup.leave()
        }
        
        self.dispatchGroup.enter()
        MPUser.observeCurrentEarnings {
            self.dispatchGroup.leave()
        }
        
        self.dispatchGroup.notify(queue: .main) {
            
            let end = Date()
            print("nAll functions completed in (end.timeIntervalSince(self.start!).rounded(toPlaces: 2)) seconds!n")
            self.sendUserToCorrectPage()
        }
    }
}

相关内容

最新更新