[英]How to interrupt Thread.sleep. Alternatives?
我已經在 OperationQueue 上實現了一個操作。
override func main() {
super.main()
if isCancelled {
return
}
if member.memberType == .timed {
triggerRestEvent(duration: member.restDuration)
}
if isCancelled {
triggerEndEvent()
}
}
triggerRestEvent
函數實際上是在調用Thread.sleep
。 一旦睡眠過期,我們就會檢查isCancelled
。
有沒有辦法在isCancelled
打開時中斷Thread.sleep
?
替代方案 - RunLoop
RunLoop 的文檔建議使用 while 循環中的自定義條件圍繞函數run
的 while 循環。 但是我將如何設置一個計時器來切換 while 循環的執行? 顯然,為了這個目的,以這種方式使用 while 循環,這些天是一種反模式嗎?
Thread.sleep
是不可取消的並且會阻塞一個線程。 在RunLoop
上旋轉是低效的。 話雖如此,有幾種選擇:
如今,為了管理異步任務之間的依賴關系,我們將使用 Swift 並發的Task
而不是Operation
。 在 Swift 並發中,我們有Task.sleep
,與Thread.sleep
不同,它是可取消的並且不會阻塞線程。
如果您想留在OperationQueue
模式中,您將使用異步自定義Operation
子類(可能是此處或此處顯示的AsynchronousOperation
),然后您將使用計時器。 您可以將DispatchSourceTimer
或Timer
或asyncAfter
與可取消的DispatchWorkItem
一起使用。 你選擇哪個真的不重要。 關鍵是確保cancel
實現使Timer
無效或取消DispatchWorkItem
或DispatchSourceTimer
,例如:
class OneSecondOperation: AsynchronousOperation { weak var timer: Timer? override func main() { DispatchQueue.main.async { self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { [weak self] _ in self?.finish() } } } override func cancel() { super.cancel() timer?.invalidate() finish() } }
請注意,您定期檢查isCancelled
的模式僅適用於現有循環。 例如,如果您正在進行一些迭代計算,那么這是一個非常合理的模式。 但是,如果您只是在等待,那么僅僅為了檢查isCancelled
而引入循環的想法是低效的。 相反,設置一個計時器並實現cancel
方法,如上所示。
無論哪種方式,您都希望實現不會阻塞線程並且可以取消。 使用Operation
子類,您必須自己實現。 使用 Swift 並發,您可以免費獲得。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.