Setting up a 60 minute timer with pause function - vb.net

thanks in advance for any help you can give.
I am trying to set up a 60 minute timer and so far that was the easy part:
Dim Breaktime As Date
Sub Timer2Tick(sender As Object, e As EventArgs)
Dim Breaktimer As TimeSpan = breaktime - DateTime.Now.AddSeconds(-1)
Breaklabel.Text = breaktimer.Minutes.ToString("00") & ":" & breaktimer.Seconds.ToString("00")
If Breaklabel.Text = "00:00" Then
Timer1.Stop()
MsgBox("Time Over")
End If
End Sub
My start button is just a simple start function
Timer2.Start()
button1.Visible = False
button2.Visible = true
then I have a stop button that stops the timer and makes the start button visible.
Timer2.STOP()
button2.Visible = False
button1.Visible = true
the issue I am having is that the timer is based on Datetime which means when I resume it, it resumes the timer based on the system clock.
What I am trying to do is set up a 60 minute timer in the MM:SS format that is not based on Datetime but for the life of me I cannot get the system to translate 3600 seconds into the MM:SS format and count down the same way as the DateTime does.
Any ideas.

This is the bones of what you need to do:
Private countdownStopwatch As New Stopwatch
Private timePeriod As TimeSpan = TimeSpan.FromMinutes(60)
Private Sub StartStop(Optional resetElapsedTime As Boolean = True)
If countdownStopwatch.IsRunning Then
'Stop the Stopwatch and the Timer.
countdownStopwatch.Stop()
Timer1.Stop()
If resetElapsedTime Then
'Reset the elapsed time period.
countdownStopwatch.Reset()
End If
DisplayTimeRemaining()
Else
'Start the Stopwatch and the Timer.
If resetElapsedTime Then
'Reset the elapsed time period.
countdownStopwatch = Stopwatch.StartNew()
Else
countdownStopwatch.Start()
End If
DisplayTimeRemaining()
Timer1.Start()
End If
End Sub
Private Sub PauseResume()
'Start or stop timing without resetting the elapsed time.
StartStop(False)
End Sub
Private Sub DisplayTimeRemaining()
Dim timeRemaining = timePeriod - countdownStopwatch.Elapsed
If timeRemaining < TimeSpan.Zero Then
timeRemaining = TimeSpan.Zero
End If
Label1.Text = timeRemaining.ToString("mm\:ss")
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If countdownStopwatch.Elapsed >= timePeriod Then
StartStop()
Else
DisplayTimeRemaining()
End If
End Sub
I'll leave it to you to decide when to enable and disable which Buttons and the like.

Related

How can I make a timer slower and slower until it stops?

Can someone tell me what's wrong or what I need to add to make it run the way that I want? I need to make it slower, then slower again, then make it stop.
Heres what I have tried:
Dim A As Integer
If Timer.Interval = 1 Then
A = Timer.Interval + 1000
If Timer.Interval = 1000 Then
Timer.Enabled = False
End If
End If
I want to stop the timer after a specific time but I have button 1 and 2 its random and stop, if I push the button random it will select any on given list then if I push stop the selection of random is going stop delay like spinning wheel, the missing on my program is the delay selection after a seconds its like selecting random then it will slowly selecting then it will stop.
Here's the btnRandom.Click event handler:
Private Sub btnRandom_Click(sender As Object, e As EventArgs) Handles btnRandom.Click
If lstList1.Items.Count <= 1 Then
MessageBox.Show("Name must more than 1 to run the randomizer.", "Error Loading", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
txtName.Enabled = False
btnRandom.Enabled = False
btnAdd.Enabled = False
btnRemove.Enabled = False
btnStop.Enabled = True
btnAdd.ForeColor = Color.FromArgb(64, 64, 64)
btnRemove.ForeColor = Color.FromArgb(64, 64, 64)
btnRandom.ForeColor = Color.FromArgb(64, 64, 64)
If btnRandom.Enabled = False Then
Timer2.Start()
lstList1.ClearSelected()
End If
End If
End Sub
And the Timer.Tick handler:
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
If btnRandom.Enabled = True Then
Timer2.Enabled = False
End If
If btnRandom.Enabled = False Then
txtNameLabel.Text = lstList1.Items(Rnd() * (lstList1.Items.Count - 1))
lstList1.SelectedItem = txtNameLabel.Text
txtNameLabel.Text = lstList1.SelectedItem
End If
End Sub
If you want something to decelerate then you need to multiply the speed by a constant less than one, which in this case is equivalent to increasing the display time interval by a constant greater than one.
So, you can start something at one speed, and then add a deceleration by changing the amount the interval is changed by.
Something like this:
Public Class Form1
Dim sw As Stopwatch
Dim tim As Timer
Dim intervalMultiplier As Double = 1.0
Dim itemsToDisplay As List(Of String)
Dim itemIndex As Integer = 0
Private Sub tim_Tick(sender As Object, e As EventArgs)
' When intervalMultiplier > 1.0 the time between ticks will increase.
tim.Interval = CInt(tim.Interval * intervalMultiplier)
Label1.Text = itemsToDisplay(itemIndex)
If tim.Interval >= 1000 Then
tim.Stop()
End If
itemIndex = (itemIndex + 1) Mod itemsToDisplay.Count
End Sub
Private Sub StartTimer()
If tim Is Nothing Then
tim = New Timer()
AddHandler tim.Tick, AddressOf tim_Tick
End If
If sw Is Nothing Then
sw = Stopwatch.StartNew()
Else
sw.Restart()
End If
intervalMultiplier = 1.0
tim.Interval = 100
tim.Start()
End Sub
Private Sub bnStop_Click(sender As Object, e As EventArgs) Handles bnStop.Click
intervalMultiplier = 1.25
End Sub
Private Sub btnRandom_Click(sender As Object, e As EventArgs) Handles btnRandom.Click
' Your code to disable buttons etc. goes here.
StartTimer()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Set up some data for this example.
itemsToDisplay = New List(Of String) From {"Capacitor", "Diode", "Inductor", "Resistor", "Transistor"}
End Sub
End Class

How to make a countdown timer that a custom control

I am trying to create a count down timer control that I will be adding to a bigger project later. The control I am trying to make is a countdown timer that is given an initial value of 60 secs but also allows the user to change that value if needed. I am doing this in Visual Studio using Visual Basics.
Public Class UserControl1
Dim timeTick As Integer
Dim min As Integer
Dim setSecs As Integer = 60
Dim sec As Integer = 120
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer.Start()
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
sec -= 1
min = sec % 60
Label1.Text = min & " : " & sec
If sec < 60 Then
min = 1 + timeTick
Label1.Text = min & " : " & sec
End If
End Sub
Property HowLong As Integer
Get
Return setSecs
End Get
Set(value As Integer)
setSecs = value
End Set
End Property
End Class
Set your Timer Interval to something less than one second; I used 250.
Then store the time in the future that is XXX seconds away, representing your countdown duration.
At each tick, simply subtract the current time from the stored future time to get a TimeSpan. Update your label with the TimeSpan value using ToString().
When the HowLong property is changed, update the target time and restart your timer...easy peesy.
All together, it'd look something like this:
Public Class UserControl1
Private target As DateTime
Private setSecs As Integer = 60
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
target = DateTime.Now.AddSeconds(HowLong)
Timer.Start()
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
Dim ts As TimeSpan = target.Subtract(DateTime.Now)
If ts.TotalMilliseconds > 0 Then
Label1.Text = "-" & ts.ToString("mm\:ss")
Else
Label1.Text = "00:00"
Timer.Stop()
End If
End Sub
Property HowLong As Integer
Get
Return setSecs
End Get
Set(value As Integer)
setSecs = value
Timer.Stop()
target = DateTime.Now.AddSeconds(HowLong)
Timer.Start()
End Set
End Property
End Class
The authors response:
Technically your way will work to I will post my solution below I did
it slightly differently. – Thomas
From my comments on the authors own submission:
The problem with this type of approach is that the Timer control is
not accurate. It is only guaranteed to not fire before the interval
has transpired. In fact it will almost always fire after the interval
with some extra "slop". For short periods (seconds/minutes), you won't
notice. For longer periods (hours), you will, as the accumulated slop
becomes bigger as time passes. Whether this matters is completely
dependent upon your application. – Idle_Mind
Technically speaking, here's a quick example of how inaccurate simply incrementing/decrementing a counter using a 1 second Timer can be:
' Timer1.Interval was set to 1000 (timer fires every "second")
Private seconds As Integer = 0
Private start As DateTime = DateTime.Now
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
seconds = seconds + 1
Label1.Text = seconds
Label2.Text = DateTime.Now.Subtract(start).TotalSeconds
End Sub
After only 1 hour and 15 minutes, the counter method on the left is already off by 4 seconds from the actual time that has passed:
A key advantage of the DateTime/TimeSpan method is that the time calculation is independent from the Timer. That is to say that the frequency at which the Timer fires has no bearing on how accurate the time calculation is.
This code below is how I made a simple timer control that countdown from a set value. Also, it has 2 buttons that pause and resume the time. This control will not work if in design mode and the timer interval is set to 1000. If you have any questions about how it works just leave a comment.
Public Class UserControl1
Dim timeRemaing As Integer = 60
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer.Start()
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
Dim sec As Integer
Dim mins As Integer
Dim timerFormat As String
If Not Me.DesignMode Then
sec = timeRemaing Mod 60
mins = timeRemaing \ 60
If sec < 10 Then
timerFormat = mins.ToString + ":0" + sec.ToString
Else
timerFormat = mins.ToString + ":" + sec.ToString
End If
If timeRemaing > 0 Then
timeRemaing -= 1
lblTime.Text = timerFormat
Else
Timer.Stop()
lblTime.Text = "The Time has Stop!!!"
End If
End If
End Sub
Public Property HowLong As Integer
Get
Return timeRemaing
End Get
Set(value As Integer)
If value <= 0 Then
Timer.Stop()
ElseIf value > 0 Then
Timer.Start()
timeRemaing = value
End If
End Set
End Property
Private Sub btnPause_Click(sender As Object, e As EventArgs) Handles btnPause.Click
Timer.Stop()
End Sub
Private Sub btnResume_Click(sender As Object, e As EventArgs) Handles btnResume.Click
Timer.Start()
End Sub
End Class

Visual Basic - start stopwatch for measuring overtime after a given amount of minutes

I'm starting my first steps into Visual Basic and trying to create sort of a stopwatch.
My design is the following:
The idea behind is to create a tool to support a debate. Persons gets a certain time (7 minutes) for presenting their topic and after that time there is room for interactive conversation (Q&A) set to 13 minutes. The idea is that after 7 minutes a buzzer sounds to stop the presenting time and go over to the interactive part. And after 20 minutes a 2nd stopwatch starts with a buzzer and a red flashing background to indicate that session needs to be terminated.
This is what I already got and I'm pretty shure it can be coded otherwise and maybe easier.
I already got it to the first working stopwatch but I don't get the rest working:
Public Class Form1
Private Hundredths As Integer = 0
Private Seconds As Integer = 0
Private Minutes As Integer = 0
Private Hours As Integer = 0
Private OvertimeHundredths As Integer = 0
Private OvertimeSeconds As Integer = 0
Private OvertimeMinutes As Integer = 0
Private OvertimeHours As Integer = 0
Private Sub StartBtn_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
If Timer1.Enabled Then
Timer1.Stop()
StartBtn.Text = "START"
Return
End If
If Not Timer1.Enabled Then
Timer1.Start()
StartBtn.Text = "STOP"
Return
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Hundredths += 1
HundredthsTxB.Text = Hundredths.ToString
SecondsTxB.Text = Seconds.ToString
MinutesTxB.Text = Minutes.ToString
HoursTxB.Text = Hours.ToString
If Hundredths = 10 Then
Seconds += 1
Hundredths = 0
End If
If Seconds = 60 Then
Minutes += 1
Seconds = 0
End If
If Minutes = 60 Then
Hours += 1
Minutes = 0
End If
If Hours = 24 Then
Timer1.Stop()
End If
End Sub
Private Sub ResetBtn_Click(sender As Object, e As EventArgs) Handles ResetBtn.Click
Hundredths = 0
Seconds = 0
Minutes = 0
Hours = 0
HundredthsTxB.Text = Hundredths.ToString
SecondsTxB.Text = Seconds.ToString
MinutesTxB.Text = Minutes.ToString
HoursTxB.Text = Hours.ToString
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
OvertimeHundredths += 1
OvertimeHundredthsTxB.Text = OvertimeHundredths.ToString
OvertimeSecondsTxB.Text = OvertimeSeconds.ToString
OvertimeMinutesTxB.Text = OvertimeMinutes.ToString
OvertimeHoursTxB.Text = OvertimeHours.ToString
If OvertimeHundredths = 10 Then
OvertimeSeconds += 1
OvertimeHundredths = 0
End If
If OvertimeSeconds = 60 Then
OvertimeMinutes += 1
OvertimeSeconds = 0
End If
If OvertimeMinutes = 60 Then
OvertimeHours += 1
OvertimeMinutes = 0
End If
If OvertimeHours = 24 Then
Timer2.Stop()
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If Timer1.Interval = 2 Then
Timer2.Start()
End If
End Sub
End Class
So any help is welcome. Also I'm keen on learning on how other guru's are thinking and coding.
Instead of using timers, I would use a Stopwatch. This way there is less messing around adding numbers etc. The code below accomplishes what you want apart from sounding a buzzer as I'm presuming you want to implement it your own. It looks worse than it is, but seems to work ok. See code comments for a little explanation
Public Class Form1
Private PresentationTimer As New Stopwatch
Private InteractiveTimer As New Stopwatch
Private PresentationMinutes As Integer
Private InteractiveMinutes As Integer
'When this timer is enabled, it keeps track of the two stopwatches and checks
'that they're within the alloted time.
'
'When the presentation timer has expired, that one is stopped and the interactive
'timer is started
'
'When the interactive timer has expired, the timer for background flashing starts.
'To stop the flashing, click the reset button on the form
Private Sub UiUpdateTimer_Tick(sender As Object, e As EventArgs) Handles uiUpdateTimer.Tick
UpdateUI()
If PresentationTimer.IsRunning And IsTimeExpired(PresentationTimer, PresentationMinutes) Then
PresentationTimer.Stop()
InteractiveTimer.Start()
'add code here for buzzer to show end of presentation time
End If
If InteractiveTimer.IsRunning And IsTimeExpired(InteractiveTimer, InteractiveMinutes) Then
InteractiveTimer.Stop()
BackgroundFlashTimer.Enabled = True
'add code here for buzzer to show end of interactive time
StartBtn.Text = "START"
End If
End Sub
'checks if the timer passed as a parameter is expired by comparing
'the number of elapsed minutes with the number of minutes passed in
'the second parameter
Private Function IsTimeExpired(tmr As Stopwatch, mins As Integer) As Boolean
If tmr.Elapsed.Minutes >= mins Then
Return True
Else
Return False
End If
End Function
'simply updates all the textboxes with the stopwatch values.
Private Sub UpdateUI()
HundredthsTxB.Text = Int(PresentationTimer.Elapsed.Milliseconds / 10).ToString
SecondsTxB.Text = PresentationTimer.Elapsed.Seconds.ToString
MinutesTxB.Text = PresentationTimer.Elapsed.Minutes.ToString
HoursTxB.Text = PresentationTimer.Elapsed.Hours.ToString
OvertimeHundredthsTxB.Text = Int(InteractiveTimer.Elapsed.Milliseconds / 10).ToString
OvertimeSecondsTxB.Text = InteractiveTimer.Elapsed.Seconds.ToString
OvertimeMinutesTxB.Text = InteractiveTimer.Elapsed.Minutes.ToString
overtimeHoursTxB.Text = InteractiveTimer.Elapsed.Hours.ToString
End Sub
Private Sub StartBtn_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
'if either timer is running, stop them both and exit this sub
If PresentationTimer.IsRunning Or InteractiveTimer.IsRunning Then
PresentationTimer.Stop()
InteractiveTimer.Stop()
StartBtn.Text = "START"
uiUpdateTimer.Enabled = False
Exit Sub
End If
'if the presentation timer hasn't run yet, check if the minutes values are
'valid and start it
If PresentationTimer.ElapsedMilliseconds = 0 Then
PresentationMinutes = CInt(Val(PresentationMinutesTxB.Text))
InteractiveMinutes = CInt(Val(InteractiveMinutesTxB.Text))
'if the minutes values are't valid show messagebox and exit this sub
If PresentationMinutes = 0 Or InteractiveMinutes = 0 Then
MessageBox.Show("Please enter valid Presentation and Interactive times.")
Exit Sub
End If
'if minutes values are ok start the presentation timer
uiUpdateTimer.Enabled = True
PresentationTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
'if the presentation timer has been running, but is currently stopped,
'continue the timer and exit this sub
If Not PresentationTimer.IsRunning And PresentationTimer.ElapsedMilliseconds > 0 Then
uiUpdateTimer.Enabled = True
PresentationTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
'if the interactive timer has been running,but is currently stopped,
'continue the timer and exit this sub
If Not InteractiveTimer.IsRunning And InteractiveTimer.ElapsedMilliseconds > 0 Then
uiUpdateTimer.Enabled = True
InteractiveTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
End Sub
Private Sub ResetBtn_Click(sender As Object, e As EventArgs) Handles ResetBtn.Click
PresentationTimer.Reset()
InteractiveTimer.Reset()
uiUpdateTimer.Enabled = False
StartBtn.Enabled = True
StartBtn.Text = "START"
UpdateUI()
BackgroundFlashTimer.Enabled = False
Me.BackColor = defaultBackColor
End Sub
Private Sub BackgroundFlashTimer_Tick(sender As Object, e As EventArgs) Handles BackgroundFlashTimer.Tick
StartBtn.Enabled = False
If Me.BackColor = DefaultBackColor Then
Me.BackColor = Color.Red
Else
Me.BackColor = DefaultBackColor
End If
Me.Update()
End Sub
End Class
This was my final solution based on David Wilson's contribution:
Public Class Form1
Private PresentationTimer As New Stopwatch
Private InteractiveTimer As New Stopwatch
Private ExtraTimeTimer As New Stopwatch
Private PresentationMinutes As Integer
Private InteractiveMinutes As Integer
'When this timer is enabled, it keeps track of the two stopwatches and checks
'that they're within the alloted time.
'
'When the presentation timer has expired, that one is stopped and the interactive
'timer is started
'
'When the interactive timer has expired, the timer for background flashing starts.
'To stop the flashing, click the reset button on the form
Private Sub uiUpdateTimer_Tick(sender As Object, e As EventArgs) Handles uiUpdateTimer.Tick
UpdateUI()
If PresentationTimer.IsRunning And IsTimeExpired(PresentationTimer, PresentationMinutes) Then
PresentationTimer.Stop()
InteractiveTimer.Start()
Me.BackColor = Color.Yellow
'add code here for buzzer to show end of presentation time
End If
If InteractiveTimer.IsRunning And IsTimeExpired(InteractiveTimer, InteractiveMinutes) Then
InteractiveTimer.Stop()
BackgroundFlashTimer.Enabled = True
ExtraTimeTimer.Start()
'add code here for buzzer to show end of interactive time
StartBtn.Text = "START"
End If
End Sub
'checks if the timer passed as a parameter is expired by comparing
'the number of elapsed minutes with the number of minutes passed in
'the second parameter
Private Function IsTimeExpired(tmr As Stopwatch, mins As Integer) As Boolean
If tmr.Elapsed.Minutes >= mins Then
Return True
Else
Return False
End If
End Function
'simply updates all the textboxes with the stopwatch values.
Private Sub UpdateUI()
HundredthsTxB.Text = Int(PresentationTimer.Elapsed.Milliseconds / 10).ToString
SecondsTxB.Text = PresentationTimer.Elapsed.Seconds.ToString
MinutesTxB.Text = PresentationTimer.Elapsed.Minutes.ToString
HoursTxB.Text = PresentationTimer.Elapsed.Hours.ToString
OvertimeHundredthsTxB.Text = Int(InteractiveTimer.Elapsed.Milliseconds / 10).ToString
OvertimeSecondsTxB.Text = InteractiveTimer.Elapsed.Seconds.ToString
OvertimeMinutesTxB.Text = InteractiveTimer.Elapsed.Minutes.ToString
OvertimeHoursTxB.Text = InteractiveTimer.Elapsed.Hours.ToString
ExtraTimeHundredthsTxB.Text = Int(ExtraTimeTimer.Elapsed.Milliseconds / 10).ToString
ExtraTimeSecondsTxB.Text = ExtraTimeTimer.Elapsed.Seconds.ToString
ExtraTimeMinutesTxB.Text = ExtraTimeTimer.Elapsed.Minutes.ToString
ExtraTimeHoursTxB.Text = ExtraTimeTimer.Elapsed.Hours.ToString
End Sub
Private Sub StartBtn_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
'if either timer is running, stop them both and exit this sub
If PresentationTimer.IsRunning Or InteractiveTimer.IsRunning Then
PresentationTimer.Stop()
InteractiveTimer.Stop()
ExtraTimeTimer.Stop()
StartBtn.Text = "START"
uiUpdateTimer.Enabled = False
Exit Sub
End If
'if the presentation timer hasn't run yet, check if the minutes values are
'valid and start it
If PresentationTimer.ElapsedMilliseconds = 0 Then
PresentationMinutes = CInt(Val(PresTimeTxB.Text))
InteractiveMinutes = CInt(Val(InterTimeTxB.Text))
'if the minutes values are't valid show messagebox and exit this sub
If PresentationMinutes = 0 Or InteractiveMinutes = 0 Then
MessageBox.Show("Please enter valid Presentation and Interactive times.")
Exit Sub
End If
'if minutes values are ok start the presentation timer
uiUpdateTimer.Enabled = True
PresentationTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
'if the presentation timer has been running, but is currently stopped,
'continue the timer and exit this sub
If Not PresentationTimer.IsRunning And PresentationTimer.ElapsedMilliseconds > 0 Then
uiUpdateTimer.Enabled = True
PresentationTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
'if the interactive timer has been running,but is currently stopped,
'continue the timer and exit this sub
If Not InteractiveTimer.IsRunning And InteractiveTimer.ElapsedMilliseconds > 0 Then
uiUpdateTimer.Enabled = True
InteractiveTimer.Start()
StartBtn.Text = "STOP"
Exit Sub
End If
End Sub
Private Sub ResetBtn_Click(sender As Object, e As EventArgs) Handles ResetBtn.Click
PresentationTimer.Reset()
InteractiveTimer.Reset()
ExtraTimeTimer.Reset()
uiUpdateTimer.Enabled = False
StartBtn.Enabled = True
StartBtn.Text = "START"
UpdateUI()
BackgroundFlashTimer.Enabled = False
Me.BackColor = DefaultBackColor
End Sub
Private Sub BackgroundFlashTimer_Tick(sender As Object, e As EventArgs) Handles BackgroundFlashTimer.Tick
StartBtn.Enabled = False
If Me.BackColor = DefaultBackColor Then
Me.BackColor = Color.Red
Else
Me.BackColor = DefaultBackColor
End If
Me.Update()
End Sub

Winforms timer not accurate

I have an app that uses a System.Windows.Forms.Timer and am seeing issues with the timer interval. When I use an interval of 1000 for a duration of 180 seconds the elapsed time is consistently around 183 seconds. When I use an interval of 995, the elapsed time is accurate (i.e. 180 seconds). I have tried this on 3 different PCs with the same results on each. The code below uses 2 textboxes to display the start and end times and a label as a countdown timer.
Can anyone explain this behavior?
Public Class Form1
Private WithEvents tmr As New System.Windows.Forms.Timer
Private Duration As Integer = 180
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RunTimer()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblActivityTimer.Text = FormatCounter(Duration)
tmr.Interval = 1000
End Sub
Private Sub RunTimer()
tmr.Start()
TextBox1.Text = Now.ToString()
End Sub
Private Function FormatCounter(sec As Integer) As String
Dim Hours, Minutes, Seconds As Integer
Hours = sec \ 3600
Seconds = sec Mod 3600
Minutes = Seconds \ 60
Seconds = sec Mod 60
FormatCounter = Hours.ToString.PadLeft(2, "0"c) & ":" _
& Minutes.ToString.PadLeft(2, "0"c) _
& ":" _
& Seconds.ToString.PadLeft(2, "0"c)
End Function
Private Sub tmr_Tick(sender As Object, e As EventArgs) Handles tmr.Tick
Duration -= 1
lblActivityTimer.Text = FormatCounter(Duration)
If Duration = 0 Then
TextBox2.Text = Now.ToString()
tmr.Stop()
End If
End Sub
End Class
Use a Stop Watch, it provides a set of methods and properties that you can use to accurately measure elapsed time.
Shared Sub Main(ByVal args() As String)
Dim stopWatch As New Stopwatch()
stopWatch.Start()
Thread.Sleep(10000)
stopWatch.Stop()
' Get the elapsed time as a TimeSpan value.
Dim ts As TimeSpan = stopWatch.Elapsed
' Format and display the TimeSpan value.
Dim elapsedTime As String = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)
Console.WriteLine( "RunTime " + elapsedTime)
End Sub 'Main
There are two readily available Timer object alternatives:
System.Threading.Timer (explained here, my first pick)
System.Timers.Timer (explained here)

Issue with Progressbar in VB2012

I am trying to add a ProgressBar to my program. The program basically compares two values of time and when the values are equal a MessageBox appears to indicate that time is up. I need the ProgressBar to load based on the time difference of the two values. One of the values in a clock and the other is input by the user (similar to an alarm).
My code:
Imports System.Net.Mime.MediaTypeNames
Public Class Form1
Private hour As Integer = 0
Private minute As Integer = 0
Private second As Integer = 0
Public Sub show_time()
second += 1
If second = 59 Then
second = 0
minute += 1
If minute = 59 Then
minute += 1
hour += 1
End If
End If
Label3PrgressStdPC.Text = hour.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= minute.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= second.ToString.PadLeft(2, "0")
Label3PrgressStdPC.Refresh()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
show_time()
If TextBox1.SelectedText = TextBox1.Text Then Exit Sub
If TextBox1.Text = Label3PrgressStdPC.Text Then
Timer1.Stop()
MsgBox("time is up")
End If
End Sub
Private Sub Bn_start_St01_Click(sender As Object, e As EventArgs) Handles Bn_start_St01.Click
Timer1.Start()
Timer1.Enabled = True
Timer2.Start()
Timer2.Enabled = True
End Sub
**Private Sub ProgressBar1_Click(sender As Object, e As EventArgs) Handles ProgressBar1.Click
ProgressBar1.Maximum = , the max progrssbr will be determine by user input
ProgressBar1.Minimum = 0**
End Sub
**Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
progresbar1.value = ,Not so sure how to write the logic here**
End Sub
End Class
Can anyone help me out i am really getting frustrated.....thanks
How about something like this...
Private Ticker As Timer = New Timer 'Create a timer
Private Start As DateTime 'Store when we start
Private Expire As DateTime 'and when we end
'Call this to get things going
Sub Begin(EndHour As Integer, EndMinute As Integer, EndSecond As Integer)
Start = DateTime.Now
'If input is a time today ...
Expire = DateTime.Now.Date.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'or just a number of hours/mins/secs from now...
Expire = DateTime.Now.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'When the timer fires, call Tick()
AddHandler Ticker.Elapsed, Sub() Tick()
Ticker.Enabled = True
Ticker.Interval = 1000
Ticker.Start
End Sub
Private Sub Tick()
If DateTime.Now < Expire Then
'Not Finished
Dim Elapsed = DateTime.Now.Subtract(Start)
Dim TotalMillis = Expire.Subtract(Start).TotalMilliseconds
Dim ProgressDouble = Elapsed.TotalMilliseconds / TotalMillis
'Me.Invoke is used here as the timer Tick() occurs on a different thread to the
'one used to create the UI. This passes a message to the UI telling it to
'update the progress bar.
Me.Invoke(Sub()
ProgressBar1.Value = CInt(ProgressDouble * ProgressBar1.Maximum)
Label3PrgressStdPC.Text = Elapsed.ToString
End Sub)
Else
'Done
MessageBox.Show("Done")
Ticker.Stop
End If
End Sub
See VB.NET Delegates and Invoke - can somebody explain these to me? for more information on Invoking.