VB.Net Countdown timer

Simon Scott 306 Reputation points
2021-06-17T13:12:16.467+00:00

Afternoon coding guru's!

I have built an application which runs some code every 60 seconds.

What i'd like to do is show the countdown on the application screen but can't fathom out how to do it!

Can anyone assist me with this please?

Thanks
Simon

Developer technologies VB
{count} votes

Accepted answer
  1. Dewayne Basnett 1,381 Reputation points
    2021-06-17T15:29:48.453+00:00

    This can only be called once. When it reaches zero it starts over.

        Private Sub CountDown()
            Static OnlyOne As New Object
            Static _wait As New Threading.ManualResetEvent(False)
            Static stpw As New Stopwatch
            Static CntDwnFrm As New TimeSpan(0, 0, 60)
            If Threading.Monitor.TryEnter(OnlyOne) Then
                stpw.Restart()
                Dim t As task 'background task
                t = Task.Run(Sub()
                                 Do
                                     Do
                                         Me.BeginInvoke(Sub()
                                                            Label1.Text = String.Format("{0:n0}",
                                                                                        (CntDwnFrm - stpw.Elapsed).TotalSeconds)
                                                        End Sub)
    
                                         If stpw.Elapsed >= CntDwnFrm Then
                                             'blast off
                                             stpw.Restart()
                                         End If
                                     Loop While _wait.WaitOne(1000)
                                 Loop
                                 Threading.Monitor.Exit(OnlyOne)
                             End Sub)
            End If
        End Sub
    
    1 person found this answer helpful.

4 additional answers

Sort by: Most helpful
  1. Castorix31 90,521 Reputation points
    2021-06-17T14:05:38.613+00:00

    You can use a Label like in this sample : How to display a countdown timer
    or you can display it in Paint event of the main Form, by refreshing it every second

    0 comments No comments

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2021-06-17T18:35:55.043+00:00

    The following class will give you a countdown (note the required module). Place the class and code module into separate files.

    Public Class CountDownTimer
        Implements IDisposable
    
        Public _stopWatch As New Stopwatch()
    
        Public TimeChanged As Action
        Public CountDownFinished As Action
    
        Public ReadOnly Property IsRunning() As Boolean
            Get
                Return timer.Enabled
            End Get
        End Property
    
        Public Property StepMs() As Double
            Get
                Return timer.Interval
            End Get
            Set
                timer.Interval = value
            End Set
        End Property
    
        Private ReadOnly timer As New Timer()
    
        Private _max As TimeSpan = TimeSpan.FromMilliseconds(30000)
    
        Public ReadOnly Property TimeLeft() As TimeSpan
            Get
                Return If((
                    _max.TotalMilliseconds - _stopWatch.ElapsedMilliseconds) > 0, 
                          TimeSpan.FromMilliseconds(_max.TotalMilliseconds - _stopWatch.ElapsedMilliseconds), 
                          TimeSpan.FromMilliseconds(0))
            End Get
        End Property
    
        Private ReadOnly Property _mustStop() As Boolean
            Get
                Return (_max.TotalMilliseconds - _stopWatch.ElapsedMilliseconds) < 0
            End Get
        End Property
    
        Public ReadOnly Property TimeLeftInSeconds() As String
            Get
                Return TimeLeft.ToString("ss")
            End Get
        End Property
    
        Public ReadOnly Property TimeLeftMinutesSecondsMilliSeconds() As String
            Get
                Return TimeLeft.ToString("mm\:ss\.fff")
            End Get
        End Property
    
        Private Sub TimerTick( sender As Object,  e As EventArgs)
    
            TimeChanged?.Invoke()
    
            If _mustStop Then
                CountDownFinished?.Invoke()
                _stopWatch.Stop()
                timer.Enabled = False
            End If
    
        End Sub
        ''' <summary>
        ''' Setup with minutes and seconds
        ''' </summary>
        ''' <param name="minutes"></param>
        ''' <param name="seconds"></param>
        Public Sub New( minutes As Integer,  seconds As Integer)
            SetTime(minutes, seconds)
            Initialize()
        End Sub
        ''' <summary>
        ''' Setup with TimeSpan
        ''' </summary>
        ''' <param name="ts"><see cref="TimeSpan"/></param>
        Public Sub New(ts As TimeSpan)
            SetTime(ts)
            Initialize()
        End Sub
    
        Public Sub New()
            Initialize()
        End Sub
    
        Private Sub Initialize()
            StepMs = 1000
            AddHandler timer.Elapsed, AddressOf TimerTick
        End Sub
    
        Public Sub SetTime(ts As TimeSpan)
            _max = ts
            TimeChanged?.Invoke()
        End Sub
    
        Public Sub SetTime(minutes As Integer, Optional seconds As Integer = 0)
            SetTime(TimeSpan.FromSeconds(minutes * 60 + seconds))
        End Sub
    
        Public Sub Start()
            timer.Start()
            _stopWatch.Start()
        End Sub
    
        Public Sub Pause()
            timer.Stop()
            _stopWatch.Stop()
        End Sub
    
        Public Sub [Stop]()
            Reset()
            Pause()
        End Sub
    
        Public Sub Reset()
            _stopWatch.Reset()
        End Sub
    
        Public Sub Restart()
            _stopWatch.Reset()
            timer.Start()
        End Sub
    
        Public Sub Dispose() Implements IDisposable.Dispose
            timer.Dispose()
        End Sub
    End Class
    

    Protect against cross threading

    Public Module Extensions
        <Runtime.CompilerServices.Extension>
        Public Sub InvokeIfRequired(Of T As ISynchronizeInvoke)( control As T,  action As Action(Of T))
            If control.InvokeRequired Then
                control.Invoke(New Action(Sub() action(control)), Nothing)
            Else
                action(control)
            End If
        End Sub
    
    End Module
    

    Form with one button, one label

    Public Class Form1
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Label1.Text = "60"
    
            Dim timer As New CountDownTimer
            timer.SetTime(0, 60)
            timer.Start()
    
            timer.TimeChanged = New Action(Sub()
                Label1.InvokeIfRequired(Sub(lb)
                    Label1.Text = timer.TimeLeftInSeconds
                End Sub)
            End Sub)
    
            timer.CountDownFinished = New Action(Sub()
                timer.Stop()
                MessageBox.Show("Done")
            End Sub)
    
    
        End Sub
    
    End Class
    

  3. Simon Scott 306 Reputation points
    2021-06-19T10:03:32.18+00:00

    Thanks for all your responses.

    I have used the solution recommended by @Dewayne Basnett which works perfectly.

    Simon

    0 comments No comments

  4. Tyler Brown 0 Reputation points
    2023-04-29T19:55:05.0766667+00:00

    Hi I am trying to use visual basic to make a bird fly across the window and I want it to do so repeatedly and dont know how to make a timer loop after a set number of ticks does anyone have an idea?

    The language I need to use is Windows Forms App (.Net Framework)


Your answer

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