View Single Post
 
Old 07-29-2014, 10:08 AM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,026
Default

Counting time using timer ticks is not very accurate, the tick intervals are not consistent and your time count versus actual time will drift.
I also noticed that whatever time was enter, say 2 minutes, ran 2:02 or 5 minutes, ran 5:05.
That is because you made each minute 59 seconds, instead of 60 (same with minutes to hours, but I never ran that long).

You can use the timer for periodically updating the GUI, but you need a more accurate source for counting the passage of time. You can use the time of day, and various other means, but I usually prefer using a StopWatch object.
I usually use the ElapsedMilliseconds property for seeing how much time has passed.
Also, it is best to use a single timer and some logic within the timer to do different things at different rates, if needed, rather than use multiple timers.

So, I just played around with the code a bit and made some modifications to use a stopwatch.
It seems like what you had for the ProgressBar was pretty much OK, tt just didn't need a separate timer and perhaps a little protection to make sure you don't exceed the maximum value.

You were multiplying Textbox1.Text by 60, so my assumption is the user enters how many minutes they want to time and you're converting that to seconds. I further convert that to milliseconds where needed to compare to the stopwatch and stop when the allotted time has passed.
You could subtract the elapsed time from the maximum value instead, so the bar starts at maximum and shrinks down to 0 when the time runs out.
Code:
    ProgressBar1.Value = Math.Max(ProgressBar1.Maximum - csw, 0) 'reduced down to 0 over time
I did change the time display to take advantage of some of the built in formatting, using TimeSpan to convert elapsed milliseconds to seconds, and then timeSpan to DateTime for display as hh:mm:ss.

I have Option Strict turned on by default, so had to add a CInt a couple of places to satisfy implicit conversions. You should probably have Option Strict turned on as well, so you get used to explicitly matching data types or converting when necessary.
Code:
'Imports System.Net.Mime.MediaTypeNames

Public Class Form1
  'Private hour As Integer = 0
  'Private minute As Integer = 0
  'Private second As Integer = 0
  Private EndTime As Integer

  Private sw As New Stopwatch

  Public Sub show_time()
    'second += 1
    'If second = 60 Then
    '  second = 0
    '  minute += 1
    '  If minute = 60 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()
    Dim ti As TimeSpan = TimeSpan.FromSeconds(sw.ElapsedMilliseconds / 1000)
    Dim td As DateTime = New DateTime(ti.Ticks)
    Label3PrgressStdPC.Text = td.ToString("HH:mm:ss")

  End Sub

  Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Dim csw As Integer = CInt(sw.ElapsedMilliseconds) 'assume won't run sw long enough (around 25 days) to exceed an Integer

    '    ProgressBar1.Value = ProgressBar1.Value + 1 '  I dont know what to do from here i need help
    ProgressBar1.Value = Math.Min(csw, ProgressBar1.Maximum) 'don't exceed ProgressBar1.Maximum value

    show_time()
    If TextBox1.SelectedText = TextBox1.Text Then Exit Sub
    '  If TextBox1.Text = Label3PrgressStdPC.Text Then
    ' If ElapsedTime = EndTime Then
    If csw >= EndTime * 1000 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
    sw.Reset()
    EndTime = CInt(Val(TextBox1.Text) * 60)
    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = EndTime * 1000
    ProgressBar1.Value = 0
    sw.Start()
    Timer1.Start()
    'Timer2.Start()
    'Timer2.Enabled = True

  End Sub

  'Private Sub ProgressBar1_Click(sender As Object, e As EventArgs) Handles ProgressBar1.Click
  '  ProgressBar1.Maximum = Val(TextBox1.SelectedText)
  '  ProgressBar1.Minimum = 0

  'End Sub

  'Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  '  ProgressBar1.Maximum = Val(TextBox1.Text)
  '  ProgressBar1.Maximum = 0
  'End Sub

End Class
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 07-29-2014 at 10:16 AM.
Reply With Quote