微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift - 启动/停止同步操作队列

如何解决Swift - 启动/停止同步操作队列

我有一些需要同步运行的操作。我试图关注this link,但对于我的情况还不够清楚。

op2 在 op1 完成之前不会启动,op3 在 op2 完成之前不会启动,但在此期间我需要能够停止任何操作并重新开始。例如,如果 op2 正在运行,我知道它无法停止,但无论出于何种原因,我都需要能够阻止 op3 执行,因为 op1 已重新启动。我该怎么做?

这是一个很简单的例子,实际代码比较复杂

const node1 = obj.nodes1[0]; // typed as Base | Child

解决方法

这是一个未经测试的实现,它允许在任何任务正在执行其子任务(重复)时取消。

如果第二个任务失败/抛出,它会自动从第一个任务重新启动。

如果用户手动停止/启动,最后一个正在进行的任务会退出它的执行(尽快)。

注意:您必须根据自己的实现处理 [weak self] 部分。

import Foundation

class TestWorker {
    let workerQueue = DispatchQueue.global(qos: .utility)
    var currentWorkItem: DispatchWorkItem?
    
    func start() {
        self.performTask { self.performTask1() }
    }
    
    func stop() {
        currentWorkItem?.cancel()
    }
    
    func performTask(block: @escaping (() -> Void)) {
        let workItem = DispatchWorkItem(block: block)
        self.currentWorkItem = workItem
        workerQueue.async(execute: workItem)
    }
    
    func performTask1() {
        guard let workItem = self.currentWorkItem else { return }
        func subtask(index: Int) {}
        for i in 0..<100 {
            if workItem.isCancelled { return }
            subtask(index: i)
        }
        self.performTask { self.performTask2() }
    }
    
    func performTask2() {
        guard let workItem = self.currentWorkItem else { return }
        func subtask(index: Int) throws {}
        for i in 0..<100 {
            if workItem.isCancelled { return }
            do { try subtask(index: i) }
            catch { 
                self.start()
                return
            }
        }
        self.performTask { self.performTask3() }
    }
    
    func performTask3() {
        guard let workItem = self.currentWorkItem else { return }
        func subtask(index: Int) {}
        for i in 0..<100 {
            if workItem.isCancelled { return }
            subtask(index: i)
        }
        /// Done
    }
}
,

也许,这是研究 Swift Combine 的一个很好的理由:

  • 将您的任务定义为 Publisher
  • 使用 flatMap 链接它们,可选择将输出从上一个传递到下一个。
  • 使用 switchToLatest 重新启动整个程序并在它仍在运行时取消前一个程序 - 如果有的话。
  • 对订阅者使用 cancel 取消整个事情。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。