I'm using that repeating timer for processing information repeatedly:
actor RepeatingTimer {
private var task: Task<Void, Never>?
private var isPaused = false
func start(duration: Double, onTick: @escaping () -> Void) {
task?.cancel() // Cancel any existing timer
isPaused = false
task = Task {
while !Task.isCancelled {
// Check if paused
if !isPaused {
onTick()
}
// Sleep for the interval
try? await Task.sleep(for: .seconds(duration))
}
}
}
func pause() {
isPaused = true
}
func resume() {
isPaused = false
}
func stop() {
task?.cancel()
task = nil
}
}`
Yet when I call it from another actor with:
await timer.start(duration: interval, onTick:{
self.process()
})
I get:
Sending 'self'-isolated value of non-Sendable type '() -> ()' to actor-isolated instance method 'start(duration:onTick:)' risks causing races in between 'self'-isolated and actor-isolated uses
Is there some more stable option for managing repeating timers, or how to solve this error?
Regarding your overall goal, Swift concurrency really needs a good equivalent to Foundation’s Timer, but I’ve yet to see any progress on that front. That’d be a good thing to raise via Swift Evolution.
Regarding your current approach, I suspect you can do a lot better than what you posted. If you want to explore improving this, my advice is that you start a thread on the Swift Forums, and specifically in Swift Forums > Using Swift area. I’ll definitely see that go by, and I’ll reply there with my own thoughts, but I’ll also be interested in hearing what the Swift experts have to say about this.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"