Looking for More Efficient Code

RogerSchlueter-7899 1,801 Reputation points
2025-12-29T03:19:00.4266667+00:00

Here is the code I've written to implement a count down timer.

A TextBox displays the time remaining in hours, minutes and seconds. The variable StartPeriod defines the starting time of the timer.

First I set up the timer:

Private Sub StartClock(sender As Object, e As RoutedEventArgs) Handles btnStart.Click
	tmr = New Timer(1000) With {.AutoReset = True, .Enabled = True}
	AddHandler tmr.Elapsed, AddressOf UpdateClock
	<< Code to set StartPeriod >>.
End Sub

Then I use this subroutine to initiate the clock update:

Private Sub UpdateClock(source As Object, e As ElapsedEventArgs)
	Dispatcher.Invoke(Sub() PopulateTimer())
End Sub

Finally, this is the subroutine that actually does the updating:

Private Sub PopulateTimer()
	If StartPeriod > 0 Then
		StartPeriod -= 1
		Dim HourCount As String = (CInt(StartPeriod) \ (60 * 60)).ToString("00:")
		Dim Remainder As Integer = CInt(StartPeriod) Mod (60 * 60)
		Dim MinuteCount As String = (Remainder \ 60).ToString("00:")
		Dim SecondCount As String = (Remainder Mod 60).ToString("00")
		txtRemaining.Text = HourCount & MinuteCount & SecondCount
	End If
End Sub

This works but is too slow; sometimes the display misses an update which usually causes the next update to jump two seconds.

Is there a faster way to do this?

Windows development | Windows App SDK
0 comments No comments

Answer accepted by question author
Anonymous
2025-12-29T07:42:12.46+00:00

Hi @RogerSchlueter-7899 ,

Timer ticks aren't precise. Subtracting 1 second per tick accumulates drift and causes jumps when ticks are missed. Instead of decrementing a counter, please try calculating remaining time from a fixed endpoint.

Here is an example based by Copilot:

Private EndTime As DateTime 

Private Sub StartClock(sender As Object, e As RoutedEventArgs) Handles btnStart.Click    
	' Set target end time once     
	EndTime = DateTime.Now.AddSeconds(StartPeriod)     
	tmr = New Timer(1000) With {.AutoReset = True, .Enabled = True}     
	AddHandler tmr.Elapsed, AddressOf UpdateClock
End Sub  

Private Sub PopulateTimer()     
	' Calculate from current time each tick     
	Dim remaining As TimeSpan = EndTime - DateTime.Now    
	If remaining.TotalSeconds > 0 Then         
		txtRemaining.Text = $"{CInt(remaining.TotalHours):00}:{remaining.Minutes:00}:{remaining.Seconds:00}"     
	Else         
		txtRemaining.Text = "00:00:00"         
		tmr.Stop()     
	End If 
End Sub  

In this approach, each tick recalculates based on the actual clock time, so any missed or delayed ticks automatically correct on the next update and no error buildup over time.

Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.