Solved

Using 2 timer controls on one single form

Posted on 2009-07-10
7
336 Views
Last Modified: 2012-05-07
Hello,

I have a windows form in vb.net 2008. This form has one timer control. This Pc is connected to 2 hardware units. My form reads the data from these 2 hardware units via the serial port. I have set the timer interval to 5 seconds. So after the first 5 seconds, I send request to serial port "1" which means data for hardware unit 1 and then I read receiving data for hardware unit 1 and then after next 5 seconds, I send request to serial port as "2" which means data for hardware unit 2 and I read the receiving data for hardware unit 2 and again after 5 seconds for hardware unit 1 and so on.

Now the client has suggested changes. He wants that I send request for hadware unit 1 after 5 seconds and the request for hardware unit 2 after 30 seconds. But I found that to implement this, I need to keep changing the timer interval after reading the data from serial port and this hangs the PC.

Hence now my question is:
1. Can I use two timer controls on one form with two different timer intervals?

2. If the above is not possible, then can I use two forms with two timer controls - one on each form with different timer internvals? The issue here would be that once I open the serial port in form 1, it may not allow me to open the port in form 2 as the serial port would be in use in form 1.

Any suggestions/solutions?

Regards,
MI
0
Comment
Question by:vj_mi
  • 4
  • 3
7 Comments
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 24829586
Yes, it it possible to use multiple Timers on the same Form but...

There are two ways to interpret your description.

Do you want:
5 secs --> Port 1
30 secs --> Port 2
5 secs --> Port 1
30 secs --? Port 2
etc...

Or?
5 secs --> Port 1
5 secs --> Port 1
5 secs --> Port 1
5 secs --> Port 1
5 secs --> Port 1
5 secs -->  Port 2
(repeat entire sequence)...

I think you want the latter?

I recommend ditching the Timer controls, though, and replacing them with BackgroundWorker controls.

Use SyncLock to prevent them from trying to access the serial port at the same time.

Here is a simplified example:
Public Class Form1
 

    Private PortLock As New Object

    Private WithEvents bgw1 As New System.ComponentModel.BackgroundWorker

    Private WithEvents bgw2 As New System.ComponentModel.BackgroundWorker
 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        bgw1.WorkerReportsProgress = True

        bgw2.WorkerReportsProgress = True

        bgw1.RunWorkerAsync()

        bgw2.RunWorkerAsync()

    End Sub
 

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

        While True ' <-- Thread will be killed automatically when app exits

            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5).TotalMilliseconds)
 

            SyncLock PortLock ' <-- Thread will STOP & WAIT here if other thread currently has "PortLock"

                ' send request to Port 1
 

                ' wait for data to come back
 

                ' process data...but do NOT update GUI from in here!
 

                bgw1.ReportProgress(-1) ' causes ProgressChanged() Event below to fire

                ' (you can pass data using a second param if desired)

            End SyncLock

        End While

    End Sub
 

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

        ' it is SAFE to update the GUI from in here...

        ' (if you passed data access it with "e.UserState")

        Debug.Print("Port 1 Progress @ " & DateTime.Now)

    End Sub
 

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

        While True ' <-- Thread will be killed automatically when app exits

            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(30).TotalMilliseconds)
 

            SyncLock PortLock ' <-- Thread will STOP & WAIT here if other thread currently has "PortLock"

                ' send request to Port 2
 

                ' wait for data to come back
 

                ' process data...but do NOT update GUI from in here!
 

                bgw2.ReportProgress(-1) ' causes ProgressChanged() Event below to fire

                ' (you can pass data using a second param if desired)

            End SyncLock

        End While

    End Sub
 

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

        ' it is SAFE to update the GUI from in here...

        ' (if you passed data access it with "e.UserState")

        Debug.Print("Port 2 Progress @ " & DateTime.Now)

    End Sub
 

End Class

Open in new window

DualBackgroundWorkerOutput.jpg
0
 

Author Comment

by:vj_mi
ID: 24830291
Hello Idle_Mind,
I want:
5 secs --> Serial Port 1 (Timer 1)
Next 30 secs --> Serial Port 1 (Timer 2)

Again 5 secs --> Serial Port 1 (using Timer 1)
Next 30 secs -- Serial Port 1 (using Timer 2)

So both data is coming from single serial port. So in this case both timer should work independently. This means that first timer can have any interval and must not be dependent and must also not interfere with timer interval of timer 2. Now I cannot remove the timer control because that will affect my complete project which is almost ready. So I appreciate this backgroundworker concept but it may not be feasible to implement at this stage.  Based on your indication that we can use two timer controls on one form, let me try a sample and I will revert back.

Regards,
MI
0
 

Author Comment

by:vj_mi
ID: 24830370
One more point:
My current code is as follows:

Dim sp as new SerialPort.

1. With this declaration, can I still use two timer controls?

2. What happens if code in timer 1 does not get completed and meantime timer2 event gets fired?

Regards,
MI
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24830889
Your Timer diagram and your description contradict each other:

    "...both timer should work independently. This means that first timer can have any interval and must not be dependent and must also not interfere with timer interval of timer 2."

With that statement you would actually have:

    5 secs Timer1 (@5 secs)
    5 secs Timer1 (@10 secs)
    5 secs Timer1 (@15 secs)
    5 secs Timer1 (@20 secs)
    5 secs Timer1 (@25 secs)
    5 secs Timer1 (@30 secs)
  30 secs Timer2 (@30 secs)
    5 secs Timer1 (@35 secs)
    5 secs Timer1 (@40 secs)
    5 secs Timer1 (@45 secs)
    5 secs Timer1 (@50 secs)
    5 secs Timer1 (@55 secs)
    5 secs Timer1 (@60 secs)
  30 secs Timer2 (@60 secs)
    etc...
   
But your diagram is showing:

    5 secs Timer1 (@5 secs)
  30 secs Timer2 (@35 secs)
    5 secs Timer1 (@40 secs)
  30 secs Timer2 (@70 secs)
    5 secs Timer1 (@75 secs)
  30 secs Timer2 (@105 secs)

If you really want the SECOND scenario then just do this:
Public Class Form1
 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Timer1.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds

        Timer2.Interval = TimeSpan.FromSeconds(30).TotalMilliseconds
 

        Timer1.Enabled = True

        Timer2.Enabled = False

    End Sub
 

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

        Timer1.Stop()
 

        ' ... code ...
 

        Timer2.Start()

    End Sub
 

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

        Timer2.Stop()
 

        ' ... code ...
 

        Timer1.Start()

    End Sub
 

End Class

Open in new window

0
 

Author Comment

by:vj_mi
ID: 24835107
Sorry ... I think I did not put it correctly, but you understood it well.... I want:
   5 secs Timer1 (@5 secs)
    5 secs Timer1 (@10 secs)
    5 secs Timer1 (@15 secs)
    5 secs Timer1 (@20 secs)
    5 secs Timer1 (@25 secs)
    5 secs Timer1 (@30 secs)
  30 secs Timer2 (@30 secs)
    5 secs Timer1 (@35 secs)
    5 secs Timer1 (@40 secs)
    5 secs Timer1 (@45 secs)
    5 secs Timer1 (@50 secs)
    5 secs Timer1 (@55 secs)
    5 secs Timer1 (@60 secs)
  30 secs Timer2 (@60 secs)
    etc...

This is what I want to have. How to achieve this? Also note that at 30 secs, both timer 1  and timer 2 would be triggered. Will this create any problem since it has to execute two different set of codes for two different timers?

Regards,
MI
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24835164
It really depends on the type of code that is executing in the Tick() events of your Timers.

The Timer control runs in the SAME thread as the form.  So if you have synchronous, non-threaded code AND you are NOT calling Application.DoEvents() inside the Tick() events, then the first Tick() event to fire and be processed will execute and run to completion without interruption.  When it is done, then the second Tick() event will be processed (including any other messages pending in the message queue).
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24835166
*Oh...to achieve this you would simply set the Interval and Enable both Timers...
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now