使用DispatchGroup进行快速线程处理 [英] Swift Threading with DispatchGroup
本文介绍了使用DispatchGroup进行快速线程处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有以下代码,它使用DispatchGroup
在任务完成时收到通知:
func getSomething(completion: ()->()) {
completion()
}
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
myGroup.enter()
getSomething {
myGroup.leave()
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
DispatchQueue.global().async {
print("We are doing background work")
doSomeWork {
print("We are done with the work - but on main thread now!!!")
}
}
所以我的问题是,我在线程上调用某个函数,该函数有一个在某个固定队列上调用的完成。
我的选项是:
- 检测Thread.isMainThread并在主队列或后台队列上通知
- 为所有函数调用传递我们正在处理的队列 问题:这不是一个真正的智能设计模式
- 处理此完成有固定队列的情况,然后再次手动调度
但我对任何选项都不满意...我不想收到这么多急件。
想象一下:
DispatchQueue.global().async {
print("We are doing background work")
doSomeWork {
DispatchQueue.global().async {
print("Now we are in background again")
}
}
}
这已经是一个级别3的闭包,使用起来并不是很好,特别是如果在后台异步调用中我们有另一个闭包或级别。
任何关于在这里做什么的帮助都是很棒的!谢谢您
推荐答案
问题是,我正在调用一个函数bla({//块代码 后台队列。Bla()在Main上调用完成处理程序 线程,由于分派组-Janosch Hübner
再次检查您的代码段
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
myGroup.enter()
getSomething {
myGroup.leave()
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
请看,因为getSomething
是同步的,所以您可以简单地编写
func doSomeWork(completion: ()->()) {
//let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
//myGroup.enter()
getSomething {
//myGroup.leave()
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
//}
}
如果getSomething
应该是异步的,请使用适当的API在某个组中运行它
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
与doSomeWork(completion: ()->())
在同一线程(最好是同一队列)上运行completion()
非常简单。
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
myGroup.wait()
completion()
//}
}
查看下一个游乐场页面,了解DispatchQueue.conCurentPerform如何更改您的设计以及Group通知的工作原理
import PlaygroundSupport
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q0 = DispatchQueue.global()
let q1 = DispatchQueue(label: "my_queue", attributes: .concurrent)
let g = DispatchGroup()
let g1 = DispatchGroup()
q0.async(group: g) {
print("1 message from (q0): will do some concurrent jobs in the background")
DispatchQueue.concurrentPerform(iterations: 5, execute: { (i) in
sleep(1)
print(" ",i)
})
print("2 message from (q0): all concurrent jobs done")
q0.async(group: g) {
print("3 some other long time running on group...")
sleep(3)
print("3 ex")
}
q0.async(group: g1) {
print("? some other long time running on gifferent group...")
sleep(4)
print("? ex")
}
g1.notify(queue: .main, execute: {
print("g1 empty")
})
}
print("4 continue on main")
g.notify(queue: q1) {
print("5 message from (q1): finished a")
DispatchQueue.main.async {
sleep(1)
print("6 from main, should stop playground execution?")
//PlaygroundPage.current.finishExecution()
}
print("7 message from (q1): finished b")
}
g1.notify(queue: .main) {
print("8 from main, g1 is empty.")
}
print(" ... continue")
哪些打印在我的环境中
1 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: will do some concurrent jobs in the background
4 continue on main
... continue
8 from main, g1 is empty.
0
2
1
3
4
2 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: all concurrent jobs done
3 some other long time running on group...
? some other long time running on gifferent group...
3 ex
5 message from <OS_dispatch_queue_concurrent: my_queue>: finished a
7 message from <OS_dispatch_queue_concurrent: my_queue>: finished b
6 from main, should stop playground execution?
? ex
g1 empty
这篇关于使用DispatchGroup进行快速线程处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文