我想知道是否有可能在保持“ .asyncAfter”时间的同时暂停然后在主队列上恢复工作项目。如果没有,是否有解决方法来实现?
在某个时候,我将以下DispatchWorkItem排队:
dispatchWorkItem = DispatchWorkItem(qos: .userInteractive, block: {
self.view.backgroundColor = UIColor.workoutBackgroundColor
self.runTimer()
self.timerButton.animateableTrackLayer.removeAnimation(forKey: "strokeEndAnimation")
self.isRestState = false
})
我使用以下方法将其排队:
DispatchQueue.main.asyncAfter(deadline: delayTime, execute: self.dispatchWorkItem))
(delayTime是该函数的参数)
现在,我遇到的问题是,如果用户在我的应用中执行“暂停”操作,如何暂停该工作项。
我尝试使用DispatchQueue.main.suspend()
方法,但是工作项在指定的延迟时间后继续执行。据我所读,此方法应该暂停队列和此排队的工作项,因为它没有被执行。 (如果我错了,请纠正我!)
我需要实现的是工作项目被“暂停”,直到用户在应用程序中执行“恢复”操作为止,该操作将从延迟时间停止的地方恢复工作项目。
这适用于不需要进行UI更新时创建的后台队列。但是,在主队列上似乎步履蹒跚。
我考虑过的一种解决方法是,用户执行暂停动作时,存储直到将要执行工作项为止的剩余时间,然后在恢复动作中将该时间重新添加到队列中。这似乎是质量很差的方法,我觉得有一种更合适的方法。
是否可以创建一个在执行时在主队列上执行工作项目的后台队列?
谢谢!
答案 0 :(得分:3)
是否可以创建一个在执行时在主队列上执行工作项目的后台队列?
您建议的是这样的
var q = DispatchQueue(label: "myqueue")
func configAndStart(seconds:TimeInterval, handler:@escaping ()->Void) {
self.q.asyncAfter(deadline: .now() + seconds, execute: {
DispatchQueue.main.async(execute: handler())
})
}
func pause() {
self.q.suspend()
}
func resume() {
self.q.resume()
}
但是我的实际测试似乎表明,这将无法按您期望的那样工作;倒计时不会从暂停的地方恢复。
我考虑过的一种解决方法是,用户执行暂停动作时,存储直到将要执行工作项为止的剩余时间,然后在恢复动作中将该时间重新添加到队列中。这似乎是质量很差的方法,我觉得有一种更合适的方法。
这不是劣质的。没有用于暂停调度计时器倒数或对计时器进行内省的内置机制,因此,如果您想在主队列上进行全部操作,那么您唯一的办法就是说:维护自己的计时器和必要的状态变量。这是我凑在一起的一个相当愚蠢的模型:
class PausableTimer {
var t : DispatchSourceTimer!
var d : Date!
var orig : TimeInterval = 0
var diff : TimeInterval = 0
var f : (()->Void)!
func configAndStart(seconds:TimeInterval, handler:@escaping ()->Void) {
orig = seconds
f = handler
t = DispatchSource.makeTimerSource()
t.schedule(deadline: DispatchTime.now()+orig, repeating: .never)
t.setEventHandler(handler: f)
d = Date()
t.resume()
}
func pause() {
t.cancel()
diff = Date().timeIntervalSince(d)
}
func resume() {
orig = orig-diff
t = DispatchSource.makeTimerSource()
t.schedule(deadline: DispatchTime.now()+orig, repeating: .never)
t.setEventHandler(handler: f)
t.resume()
}
}
这在我的粗略测试中有效,并且似乎可以根据需要中断(可暂停),但是请不要引用我;我没有花很多时间。这些细节留给读者练习!