@@ -48,22 +48,26 @@ public final actor AsyncTimer {
4848 /// This handler is called when the timer is cancelled.
4949 private var cancelHandler : CancelHandler ?
5050
51- /// Initializes a new `AsyncRepeatingTimer` instance.
51+ /// Whether the timer is running.
52+ public var isRunning : Bool { task != nil }
53+
54+ /// Initializes a new `AsyncTimer` instance.
5255 /// - Parameters:
5356 /// - interval: The interval at which the timer fires.
5457 /// - priority: The priority of the task. Default is `.medium`.
5558 /// - repeating: Whether the timer should repeat. Default is `false`.
5659 /// - firesImmediately: Whether the timer should fire immediately upon starting. Default is `true`. It is only effective when `repeating` is `true`.
5760 /// - handler: The handler that is called when the timer fires.
5861 /// - cancelHandler: The handler that is called when the timer is cancelled.
59- /// - Returns: A new `AsyncRepeatingTimer ` instance.
62+ /// - Returns: A new `AsyncTimer ` instance.
6063 public init ( interval: TimeInterval ,
6164 priority: TaskPriority = . medium,
6265 repeating: Bool = false ,
6366 firesImmediately: Bool = true ,
6467 handler: @escaping RepeatHandler ,
6568 cancelHandler: CancelHandler ? = nil )
6669 {
70+ precondition ( interval > 0 , " Interval must be greater than 0 " )
6771 self . interval = interval
6872 self . priority = priority
6973 self . firesImmediately = firesImmediately
@@ -79,24 +83,32 @@ public final actor AsyncTimer {
7983 task = Task ( priority: priority) {
8084 guard repeating else {
8185 // one-time timer
82- try await Self . sleep ( interval)
83- await self . handler ( )
86+ do {
87+ try await Self . sleep ( interval)
88+ await self . handler ( )
89+ } catch is CancellationError {
90+ // timer was cancelled
91+ await cancelHandler ? ( )
92+ }
8493 return
8594 }
8695
8796 // repeating timer
88- if !firesImmediately {
89- try await Self . sleep ( interval)
90- }
9197 do {
98+ if !firesImmediately {
99+ try await Self . sleep ( interval)
100+ }
92101 while !Task. isCancelled {
93102 await self . handler ( )
103+ if Task . isCancelled { break }
94104 try await Self . sleep ( interval)
95105 }
96106 } catch is CancellationError {
97- await cancelHandler ? ( )
98- return
99- } catch { }
107+ // timer was cancelled
108+ } catch {
109+ // unexpected error
110+ }
111+ await cancelHandler ? ( )
100112 }
101113 }
102114
@@ -117,8 +129,10 @@ public final actor AsyncTimer {
117129 /// - Parameter newInterval: The new interval at which the timer should fire.
118130 /// - Note: This will also restart the timer.
119131 public func setInterval( _ newInterval: TimeInterval ) {
132+ precondition ( newInterval > 0 , " Interval must be greater than 0 " )
133+ guard interval != newInterval else { return }
120134 interval = newInterval
121- restart ( )
135+ if isRunning { restart ( ) }
122136 }
123137}
124138
0 commit comments