GCD - asyncAfter:如何同步 运行
GCD - asyncAfter: How to run it synchronously
我刚刚开始阅读 swift,目前我对如何正确使用线程感到困惑。
我想在下面的代码块中实现的是在调度程序中执行打印语句,但我想按顺序执行。我遇到的问题是,我当然想在后台线程而不是主线程中执行此操作,因为这是一项长期任务,同时在我延迟执行时按顺序执行它。当前块一起执行每个案例。
我也查看了 Timer 和 Semaphores,但没有任何结果。
任何对我做错了什么或我应该采取什么方法的帮助或解释将不胜感激。
let formattedSeries = ["a", "a", "b"]
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
for (index, letter) in (formattedSeries.enumerated()){
switch letter {
case "a":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
print("a executed")
})
break
case "b":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
print("b executed")
})
break
default:
print("default")
}
}
要按顺序执行任务,您需要一个异步操作。
- 使用
中提供的classAsynchronousOperation
- 创建连续剧
OperationQueue
并将maxConcurrentOperationCount
设置为1
- Subclass
AsynchronousOperation
并将 dispatchQueue.asyncAfter
任务放入 subclass 的 main()
方法中。在闭包中调用 finish()
(在 print("a executed")
之前或之后)
- 将操作添加到串行操作队列
你可以使用调度组强制下一个字母的评估等待上一个字母的评估:
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
let formattedSeries = "abbaabba"
print("start", Date().timeIntervalSince1970)
for (index, letter) in (formattedSeries.enumerated()){
dispatchGroup.enter()
switch letter {
case "a":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
print("a executed", Date().timeIntervalSince1970)
dispatchGroup.leave()
})
break
case "b":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
print("b executed", Date().timeIntervalSince1970)
dispatchGroup.leave()
})
break
default:
print("default")
}
dispatchGroup.wait()
}
我添加了一些额外的输出来证明间隔是正确的。输出是
start 1580060250.3307471
a executed 1580060251.389974
b executed 1580060256.889923
b executed 1580060262.2758632
a executed 1580060263.372933
a executed 1580060264.373787
b executed 1580060269.37443
b executed 1580060274.375314
a executed 1580060275.4726748
这证明我们按顺序评估字母,并且打印之间有 async_after
间隔。
我刚刚开始阅读 swift,目前我对如何正确使用线程感到困惑。
我想在下面的代码块中实现的是在调度程序中执行打印语句,但我想按顺序执行。我遇到的问题是,我当然想在后台线程而不是主线程中执行此操作,因为这是一项长期任务,同时在我延迟执行时按顺序执行它。当前块一起执行每个案例。
我也查看了 Timer 和 Semaphores,但没有任何结果。
任何对我做错了什么或我应该采取什么方法的帮助或解释将不胜感激。
let formattedSeries = ["a", "a", "b"]
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
for (index, letter) in (formattedSeries.enumerated()){
switch letter {
case "a":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
print("a executed")
})
break
case "b":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
print("b executed")
})
break
default:
print("default")
}
}
要按顺序执行任务,您需要一个异步操作。
- 使用
- 创建连续剧
OperationQueue
并将maxConcurrentOperationCount
设置为1
- Subclass
AsynchronousOperation
并将dispatchQueue.asyncAfter
任务放入 subclass 的main()
方法中。在闭包中调用finish()
(在print("a executed")
之前或之后) - 将操作添加到串行操作队列
AsynchronousOperation
你可以使用调度组强制下一个字母的评估等待上一个字母的评估:
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
let formattedSeries = "abbaabba"
print("start", Date().timeIntervalSince1970)
for (index, letter) in (formattedSeries.enumerated()){
dispatchGroup.enter()
switch letter {
case "a":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
print("a executed", Date().timeIntervalSince1970)
dispatchGroup.leave()
})
break
case "b":
dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
print("b executed", Date().timeIntervalSince1970)
dispatchGroup.leave()
})
break
default:
print("default")
}
dispatchGroup.wait()
}
我添加了一些额外的输出来证明间隔是正确的。输出是
start 1580060250.3307471
a executed 1580060251.389974
b executed 1580060256.889923
b executed 1580060262.2758632
a executed 1580060263.372933
a executed 1580060264.373787
b executed 1580060269.37443
b executed 1580060274.375314
a executed 1580060275.4726748
这证明我们按顺序评估字母,并且打印之间有 async_after
间隔。