question

SimonScott-1980 avatar image
0 Votes"
SimonScott-1980 asked rich edited

VB.Net Countdown timer

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

dotnet-visual-basic
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Is this a console program? If not then you should use a tag to indicate whether you want Windows Forms or WPF code.

0 Votes 0 ·
DewayneBasnett-7583 avatar image
0 Votes"
DewayneBasnett-7583 answered SimonScott-1980 commented

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
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Appreciate both of your replies.

I shall do some testing tomorrow and let you know how i get on :)

0 Votes 0 ·
Castorix31 avatar image
0 Votes"
Castorix31 answered

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


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered rich edited

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


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Imports System.Timers needs to be added to the CountdownTimer class.

You have to add the system timers for this to work and when you do that, this class works great. Easy to customize as well. You have to be careful about restarting it though, as it will start a new unstoppable countdown timer. Press the button 5 times you get 5 separate timers that you can't stop. lol

0 Votes 0 ·
SimonScott-1980 avatar image
0 Votes"
SimonScott-1980 answered

Thanks for all your responses.

I have used the solution recommended by @DewayneBasnett-7583 which works perfectly.

Simon

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.