作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有两个函数(或任务),我想一个接一个地运行,我正在使用 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")
}
}
如果我使用以下代码,它们会同时运行但在后台线程中。
@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")
}
}
我一直在搜索和搜索,但我似乎无法找到我的问题的答案或对此事的清晰度。有人可以就这里发生的事情提供一些指导。这些是案例中有问题的功能。他们模拟一项长期任务来练习跟踪进度。
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()
}
这也按顺序执行它们,但是在函数内部调用 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")
}
}
最佳答案
根据您的描述,我可能根本不会在这里使用调度组。我只是链接这些方法:
@objc func doWorkFunctions() {
DispatchQueue.global(qos: .background).async {
self.firstFunction {
self.secondFunction {
DispatchQueue.main.async {
print("All tasks completed")
}
}
}
}
但是假设你有一个很好的理由在这里建立一个组,你需要做的是使用.notify
来同步它们。 .notify
表示“当组为空时,将此 block 提交到此队列。”
@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")
}
}
}
(您可能不需要 taskGroup
成为此处的实例属性。您可以将其设为局部变量并减少 self.
所需的引用。每个 block 都有对该组的引用,因此它会一直存在,直到所有 block 都完成。)
关于swift - 如何在后台线程中使用 DispatchGroup?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53972081/
我是一名优秀的程序员,十分优秀!