Looking for More Efficient Code

RogerSchlueter-7899 1,591 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
{count} votes

Answer accepted by question author
  1. Harry Vo (WICLOUD CORPORATION) 4,665 Reputation points Microsoft External Staff Moderator
    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.


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.