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
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
Is this a console program? If not then you should use a tag to indicate whether you want Windows Forms or WPF code.
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
Appreciate both of your replies.
I shall do some testing tomorrow and let you know how i get on :)
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
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
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
Thanks for all your responses.
I have used the solution recommended by @DewayneBasnett-7583 which works perfectly.
Simon
5 people are following this question.