Having a problem using two timers

I am creating a program in VB2005 express to collect resistance values from 14 devices. Within the program I use two timers. The first timer has a tick event every second that increments a counter value that is displayed in a label on the form. The second timer has a tick event every 5 minutes. The event handler for this tick calls a function that communicates to a control unit that switches between the 14 channels and reads the resistance values. All of this is through GPIB communication and works fine. The problem is that when the second (5 minute) timer event occurs the first (1 second) timer stops counting until the called function completes, which takes about 20 seconds. I want the value the first timer is incrementing to continue to update while the function is collecting data. Any guidance on the use of timers is appreciated.

Answer this question

Having a problem using two timers

  • Rambalac

    I'm no expert, but you might try placing the function to be completed (that takes 20 seconds) into a background worker, and starting the background worker from your 5 minute timer.

    If you are using the a windows form timer (windows.form.timer) they run on a single thread. You might also try the system.timers.timer. I think that it runs on a seperate thread. Somebody correct me if I am wrong please.



  • rothco

    The way you describe it, the 1st timer doesn't do anything other than keeping the user informed when the 2nd timer might do it's job. Punt: let the 1st timer display the actual amount of time expired (Now - DateSinceLastGpibScan) rather than the incremental time.



  • Uturn

    It sounds like the UI is freezing while processing your function in The Second Timer. I would use a backgroundworker component to process your funtion that is taking 20 seconds while the first timer continues to update the UI:

    Sample code modified from:

    http://msdn2.microsoft.com/en-us/library/hybbz6ke(d=ide).aspx

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    ' Do not access the form's BackgroundWorker reference directly.

    ' Instead, use the reference provided by the sender parameter.

    Dim bw As BackgroundWorker = CType(sender, BackgroundWorker)

    ' Extract the argument.

    Dim arg As Integer = CInt(Fix(e.Argument))

    ' Start the time-consuming operation.

    e.Result = TimeConsumingOperation(bw, arg)

    ' If the operation was canceled by the user,

    ' set the DoWorkEventArgs.Cancel property to true.

    If bw.CancellationPending Then

    e.Cancel = True

    End If

    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

    Me.Label2.Text = e.ProgressPercentage.ToString

    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    If e.Cancelled Then

    ' The user canceled the operation.

    MessageBox.Show("Operation was canceled")

    ElseIf (e.Error IsNot Nothing) Then

    ' There was an error during the operation.

    Dim msg As String = String.Format("An error occurred: {0}", e.Error.Message)

    MessageBox.Show(msg)

    Else

    ' The operation completed normally.

    Dim msg As String = String.Format("Result = {0}", e.Result)

    MessageBox.Show(msg)

    End If

    End Sub

    Private Function TimeConsumingOperation( _

    ByVal bw As BackgroundWorker, _

    ByVal sleepPeriod As Integer) As Integer

    Dim result As Integer = 0

    'Your 20 second function HERE

    Return result

    End Function

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

    'Your UI update from the first Timer here

    Static Count As Integer

    Me.Label1.Text = Count.ToString

    Count += 1

    End Sub

    Private Sub Timer2_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer2.Tick

    'Every 5 minutes this timer starts the background thread

    Me.BackgroundWorker1.RunWorkerAsync(2000)

    End Sub

    Since I have no clue of your actual code you will have to modify the above to get your desired result...but I hope that helps



  • Having a problem using two timers