如何取消延迟的线程?

Posted

技术标签:

【中文标题】如何取消延迟的线程?【英文标题】:How to cancel the delayed thread? 【发布时间】:2021-02-13 18:53:52 【问题描述】:

我正在执行一组任务,为了随着时间的推移跨越它们,我使用了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

【问题讨论】:

如果我需要改进问题,请在 cmets 中告诉我;以便我知道如何修复它以提高讨论质量 我认为您正在将 GCD 与线程混合。虽然他们的目标是相似的,但他们处于完全不同的水平,所以混合它们从来都不是一个好主意。如果您需要在任务之间进行更复杂的交互,我建议您使用 GCD 和 work items 或 OperationQueue 和一组 Operations。 @ScorpiCon 我想要实现的是 - 让演示文稿在幻灯片之间以预定时间运行,但如果用户想要返回(或向前);它应该直接切到上一张幻灯片,并以预定暂停的相同方式继续。你对此有什么想法吗? 【参考方案1】:

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

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

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

    更简单,只需安排 Timer 然后 invalidate 如果您想停止它。

如果您想要每 x 秒执行一些可取消的任务,则单个重复 Timer 可能是最简单的,因为您可以 invalidate 它并停止整个重复系列一步。 (它也避免了定时器合并问题。)


你说:

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

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

【讨论】:

感谢您的回答和研究阅读的链接!让我更清楚了!目前正在尝试使用 Timer 正确实现此功能。程序的响应时间是线程的 1000 倍。 酷。 FWIW,GCD 模式不应该更慢,但是对于要取消的重复内容,Timer 只是一种更简单的方法。您的 GCD 实现中可能还发生了其他事情,但我想现在您已经有了更好的解决方案烹饪......

以上是关于如何取消延迟的线程?的主要内容,如果未能解决你的问题,请参考以下文章

《java并发编程实战》读书笔记6--取消与关闭

如何在 Rails 中使用延迟作业取消预定作业?

如何从另一个线程取消 GTK3 线程?

iPhone在延迟后取消选择行

求助,怎么取消键盘延迟

可以取消 jQuery 延迟吗?