Multiple threads with Timer and Port objects

gpoch

Active member
Joined
Oct 28, 2006
Messages
34
Location
USA
Programming Experience
1-3
Hello All,

I'm working on a program that controls Pan-tilt cameras through a serial port. The commands are sent to the cameras in two ways. Either immediately or delayed up to five minutes. My current approach sends the commands to a queue collection that's checked with a timer event every second. From what I understand each of the objects (timer and port) have their own thread.

This code actually works but I think it's a very poor approach. I would also like to find a better way to remove the sent commands from the _queue collection.

VB.NET:
Private Sub queueTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _queueTimer.Elapsed
Dim cmd As Command
Dim al As New ArrayList
 
For Each cmd In _queue
 
If cmd.StartTime <= Date.Now Then
SyncLock _port
'send the command
SendCommand(cmd)
'add commands to an arraylist for removal
al.Add(cmd)
Debug.Print(cmd.FriendlyMessage)
End SyncLock
End If
Next
'Remove all completed commands
Dim i As Integer
For i = 0 To al.Count - 1
_queue.Remove(al(i))
Debug.Print(al(i).ToString)
Next
End Sub
 
Public Sub SendCommand(ByVal cmd As Command)
'See if the command should be sent now or put in a queue
If cmd.StartTime <= Date.Now Then
SyncLock _port
_port.WriteLine(cmd.GetCommandString)
End SyncLock
 
'TODO Log the event 
 
Else : _queue.Add(cmd)
 
End If
 
End Sub

I'm hoping someone could give me some advice or direction on a better approach to this.

Thanks for your help!
 
How frequent are these messages? If they're not too freuqent then I'd suggest an individual Timer for each message. Here's a very simple example that you can modify to your own needs.
VB.NET:
'The messages keyed by timer.
Private timedMessages As New Dictionary(Of Timers.Timer, String)

'Adds a timed message to the list.
Private Sub AddTimedMessage(ByVal message As String, ByVal delay As Integer)
    'Create a new timer.
    Dim tmr As New Timers.Timer(delay * 1000)

    'Attach the event handler that will display the message.
    AddHandler tmr.Elapsed, AddressOf TimerElapsed

    'Connect the message to the timer and add them to the list.
    Me.timedMessages.Add(tmr, message)
End Sub

Private Sub TimerElapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
    'Get a reference to the timer that just elapsed.
    Dim tmr As Timers.Timer = DirectCast(sender, Timers.Timer)

    'Display the message that corresponds to this timer.
    MessageBox.Show(Me.timedMessages(tmr))

    'Remove the timer and message from the list.
    Me.timedMessages.Remove(tmr)

    'Destroy the timer.
    tmr.Dispose()
End Sub
 
Thank you so much! Very clever and clean approach, it also solved all my threading problems. Thanks again jmcilhinney! :D
 
Back
Top