如何取消延迟的线程?
How to cancel the delayed thread?
我正在执行一组任务,为了随着时间的推移跨越它们,我使用了Thread.sleep(forTimeInterval: ... )
它在执行之间增加了暂停。
然后,在主屏幕上我有控制器,可以干预线程执行,所以当应用控制器时我想取消睡眠。并从用户选择的地方开始。
所以,我试过了
Thread.exit()
- 并且它以错误终止程序。
如何退出(或者,刷新)当前线程,从我想要的地方开始?
按钮(即controller)控制线程挂起的方法有哪些?
实际发生的情况是,如果我取消,它将继续 运行 只是从同一个地方...
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()
}
}
作为一般规则,我建议不要在线程上休眠。首先,我们没有预先取消。其次,这是对资源的低效使用,不必要地占用该线程。
如果您想在一段时间后做某事,您有以下几种选择:
如果您想停止它,请安排 Timer
and then invalidate
它。
如果使用 Swift 并发(例如 Task
、async
-await
等),您可以 Task.sleep
,与 Thread.sleep
不同,它检测并处理取消。 Thread.sleep
应该避免,但是对于 Swift 并发,你可以将 Task
存储在 属性 中, cancel
在适当的时候, Task.sleep
在 Task
内将优雅地处理取消。
如果您不希望这种情况发生,您可以创建一个 DispatchWorkItem
, dispatch it with asyncAfter
, and then cancel
。
如果您想要每 x 秒执行一些可取消的任务,那么重复 Timer
可能是最简单的,因为您可以 invalidate
它一步停止整个重复系列。 (它也避免了计时器合并问题。)
你说:
what I am trying to achieve is - having a presentation that runs with predetermined time between slides, but if user wants to go back (or forward); it should cut straight away to previous slide and continue in the same manner of predetermined pauses.
我建议重复 Timer
以前进到下一张幻灯片。如果用户手动切换到另一张幻灯片,invalidate
旧计时器并创建一个新的重复 Timer
。
我正在执行一组任务,为了随着时间的推移跨越它们,我使用了Thread.sleep(forTimeInterval: ... )
它在执行之间增加了暂停。
然后,在主屏幕上我有控制器,可以干预线程执行,所以当应用控制器时我想取消睡眠。并从用户选择的地方开始。
所以,我试过了
Thread.exit()
- 并且它以错误终止程序。
如何退出(或者,刷新)当前线程,从我想要的地方开始? 按钮(即controller)控制线程挂起的方法有哪些?
实际发生的情况是,如果我取消,它将继续 运行 只是从同一个地方...
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()
}
}
作为一般规则,我建议不要在线程上休眠。首先,我们没有预先取消。其次,这是对资源的低效使用,不必要地占用该线程。
如果您想在一段时间后做某事,您有以下几种选择:
如果您想停止它,请安排
Timer
and theninvalidate
它。如果使用 Swift 并发(例如
Task
、async
-await
等),您可以Task.sleep
,与Thread.sleep
不同,它检测并处理取消。Thread.sleep
应该避免,但是对于 Swift 并发,你可以将Task
存储在 属性 中,cancel
在适当的时候,Task.sleep
在Task
内将优雅地处理取消。如果您不希望这种情况发生,您可以创建一个
DispatchWorkItem
, dispatch it withasyncAfter
, and thencancel
。
如果您想要每 x 秒执行一些可取消的任务,那么重复 Timer
可能是最简单的,因为您可以 invalidate
它一步停止整个重复系列。 (它也避免了计时器合并问题。)
你说:
what I am trying to achieve is - having a presentation that runs with predetermined time between slides, but if user wants to go back (or forward); it should cut straight away to previous slide and continue in the same manner of predetermined pauses.
我建议重复 Timer
以前进到下一张幻灯片。如果用户手动切换到另一张幻灯片,invalidate
旧计时器并创建一个新的重复 Timer
。