簡體   English   中英

如何中斷 Thread.sleep。 備擇方案?

[英]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上旋轉是低效的。 話雖如此,有幾種選擇:

  1. 如今,為了管理異步任務之間的依賴關系,我們將使用 Swift 並發的Task而不是Operation 在 Swift 並發中,我們有Task.sleep ,與Thread.sleep不同,它是可取消的並且不會阻塞線程。

  2. 如果您想留在OperationQueue模式中,您將使用異步自定義Operation子類(可能是此處此處顯示的AsynchronousOperation ),然后您將使用計時器。 您可以將DispatchSourceTimerTimerasyncAfter與可取消的DispatchWorkItem一起使用。 你選擇哪個真的不重要。 關鍵是確保cancel實現使Timer無效或取消DispatchWorkItemDispatchSourceTimer ,例如:

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM