我有两个函数(或任务),我想一个接一个地运行,我正在使用 DispatchGroup 来跟踪它们并在它们完成时通知我。现在它们正在主线程中完成,但我想在后台线程中运行这些任务。我该怎么做呢?我尝试了几种方法,但它们要么同时运行,要么在第一个方法完成后出现异常错误。以下代码依次执行任务,但如果我在函数内调用 Thread.current,我可以看到它们正在主线程中运行。
@objc func doWorkFunctions(){
taskGroup.enter()
DispatchQueue.global(qos: .background).sync {
self.firstFunction {
self.taskGroup.leave()
}
}
taskGroup.enter()
DispatchQueue.global(qos: .background).sync {
self.secondFunction {
self.taskGroup.leave()
}
}
taskGroup.notify(queue: .main) {
print("All tasks completed")
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用以下代码,它们会同时运行,但在后台线程中运行。
@objc func doWorkFunctions(){
taskGroup.enter()
DispatchQueue.global(qos: .background).async {
self.firstFunction {
self.taskGroup.leave()
}
}
taskGroup.enter()
DispatchQueue.global(qos: .background).async {
self.secondFunction {
self.taskGroup.leave()
}
}
taskGroup.notify(queue: .main) {
print("All tasks completed")
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在寻找又寻找,但似乎找不到我的问题的答案或对此事的澄清。有人可以提供一些关于这里发生的事情的指导吗?这些是案例中所涉及的功能。他们模拟一项长期任务来练习跟踪进度。
func firstFunction(completion: @escaping()->Void){
print(Thread.current)
if childProgressOne.isCancelled { return }
for i in 1...5 {
sleep(1)
childProgressOne.completedUnitCount = Int64(i * 20)
print("Child Progress One: \(childProgressOne.fractionCompleted)")
print("Total Progress: \(totalProgress.fractionCompleted)")
}
completion()
}
func secondFunction(completion: @escaping()->Void){
print(Thread.current)
if childProgressTwo.isCancelled { return }
for i in 1...5 {
sleep(1)
childProgressTwo.completedUnitCount = Int64(i * 20)
print("Child Progress Two: \(childProgressTwo.fractionCompleted)")
print("Total Progress: \(totalProgress.fractionCompleted)")
}
completion()
}
Run Code Online (Sandbox Code Playgroud)
这也按顺序执行它们,但在函数内调用 Thread.current 告诉我它们正在主线程中执行,即使它们被调用到后台线程。
@objc func doWorkFunctions(){
DispatchQueue.global(qos: .background).sync {
self.taskGroup.enter()
self.firstFunction {
self.taskGroup.leave()
}
self.taskGroup.enter()
self.secondFunction {
self.taskGroup.leave()
}
}
taskGroup.notify(queue: .main) {
print("All tasks completed")
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于您所描述的,我可能根本不会在这里使用调度组。我只是链接这些方法:
@objc func doWorkFunctions() {
DispatchQueue.global(qos: .background).async {
self.firstFunction {
self.secondFunction {
DispatchQueue.main.async {
print("All tasks completed")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但假设你有充分的理由在这里建立一个组,那么你需要做的就是使用.notify它们来同步它们。.notify说“当组为空时,将此块提交到此队列。”
@objc func doWorkFunctions(){
let queue = DispatchQueue.global(qos: .background)
taskGroup.enter()
queue.async {
self.firstFunction {
self.taskGroup.leave()
}
}
taskGroup.notify(queue: queue) {
self.taskGroup.enter()
self.secondFunction {
self.taskGroup.leave()
}
self.taskGroup.notify(queue: .main) {
print("All tasks completed")
}
}
}
Run Code Online (Sandbox Code Playgroud)
(这里您可能不需要taskGroup成为实例属性。您可以将其设为局部变量并且需要更少的self.引用。每个块都有对该组的引用,因此它将一直存在,直到所有块都完成为止。)