?
Solved

Using 2 timer controls on one single form

Posted on 2009-07-10
7
Medium Priority
?
355 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 2000 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

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 86

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 86

Expert Comment

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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

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…
I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month10 days, 12 hours left to enroll

765 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