I am executing set of tasks, and in order to span them over time I've used Thread.sleep(forTimeInterval: ... ) It adds pauses between executions.
Then, on the main screen I have controllers, that can intervene into thread execution, so when controller applied I want to cancel the sleep. And start from the place of user's choice.
So, I've tried
Thread.exit() - and it terminates the program with error.
How to exit (or, refresh) the current thread and start from the place I want? What are the ways to control the suspension of thread by button (i.e. controller)?
What actually happens is that if I cancel, it continues to run just from the same place...
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()
}
EDITS:
For example, what does the cancel() do here? and why exit() can't be applied to Thread.current, but only to Thread.
"You can use these semantics to cancel the execution of a thread or determine if the thread is still executing or has finished its task". Okey, if I cancel(). What, then will start it again?
queue.sync {
Thread.sleep(forTimeInterval: TimeInterval(10.0))
// do something
}
Button("...") {
queue.sync {
Thread.current.cancel()
}
}
As a general rule, I would advise against sleeping on a thread. First, we do not have preemptive cancelation. Second, it’s an inefficient use of resources, tying up that thread unnecessarily.
If you want to do something after a certain period of time, you have a few options:
Schedule a
Timerand theninvalidateit if you want to stop it.If using Swift concurrency (e.g.,
Task,async-await, etc.), you canTask.sleep, which, unlikeThread.sleep, detects and handles cancelation.Thread.sleepshould be avoided, but with Swift concurrency, you can store theTaskin a property,cancelit when appropriate, andTask.sleepwithin theTaskwill handle cancellation elegantly.You can create a
DispatchWorkItem, dispatch it withasyncAfter, and thencancelif you don’t want that to happen.If you have some cancelable tasks that you want to perform every x seconds, a single repeating
Timeris probably easiest, as you caninvalidateit and it stops the whole repeating series in one step. (It also avoids timer coalescing problems.)You said:
I would suggest a repeating
Timerto advance to the next slide. If the user manually changes to another slide,invalidatethe old timer and create a new repeatingTimer.