3

我正在执行一组任务,为了随着时间的推移跨越它们,我使用Thread.sleep(forTimeInterval: ... )了它在执行之间添加了暂停。

然后,在主屏幕上我有控制器,可以干预线程执行,所以当控制器应用时我想取消睡眠。并从用户选择的地方开始。所以,我已经尝试过 Thread.exit()了 - 它以错误终止程序。

如何退出(或刷新)当前线程并从我想要的地方开始?按钮(即控制器)控制线程暂停的方法有哪些?

实际发生的是,如果我取消,它会继续从同一个地方运行......

let queue = DispatchQueue(label: "Actions Queue")
let delay: Double = 5
var actions = ["action 1", "action 2", "action 3", "action 4", "action 5"]


// every time task finishes, it calls for the following task (with delay)
queue.sync {
// sets an interval, that continues an action
    Thread.sleep(forTimeInterval: TimeInterval(delay))
    // continue an action
}

// heres how I've tried in main view, but it doesn't work
queue.sync {
    Thread.current.cancel()
}

编辑:

例如,cancel()这里做什么?以及为什么exit()不能应用于Thread.current,而只能应用于Thread.

“您可以使用这些语义来取消线程的执行或确定线程是否仍在执行或已完成其任务”。好吧,如果我cancel(). 什么,然后会重新开始

queue.sync {
    Thread.sleep(forTimeInterval: TimeInterval(10.0))
    // do something
}

Button("...") {
    queue.sync {
        Thread.current.cancel()
    }
}

https://developer.apple.com/documentation/foundation/thread

4

1 回答 1

1

作为一般规则,我建议不要在线程上睡觉。首先,我们没有抢先取消。其次,这是对资源的低效使用,不必要地占用了该线程。

如果你想在一段时间后做某事,你有几个选择:

  1. 您可以创建一个DispatchWorkItem,使用 调度它asyncAfter,然后cancel如果您不希望这种情况发生。

  2. 更简单的是,如果你想停止它,只需安排一个Timer然后它。invalidate

如果您有一些要每x秒执行一次的可取消任务,那么一次重复Timer可能是最简单的,因为您可以invalidate这样做,并且它会在一个步骤中停止整个重复系列。(它还避免了计时器合并问题。)


你说:

我想要实现的是 - 让演示文稿在幻灯片之间以预定时间运行,但如果用户想要返回(或向前);它应该直接切到上一张幻灯片,并以预定暂停的相同方式继续。

我建议重复Timer一下以进入下一张幻灯片。如果用户手动更改到另一张幻灯片,invalidate则旧的计时器并创建一个新的重复Timer

于 2021-02-13T21:55:15.270 回答