Solved

How to  _synchronize_ two threads

Posted on 2008-10-30
8
228 Views
Last Modified: 2013-11-07
I have (2) background workers that need to be synchronized in order for this to work correctly:the code is attached. Im trying to take two simultaneous data input from two different IO devices and read the com ports at the same time to populate there individual texct boxes.

Public Sub StartWorkerThreadDualDSI1(ByVal gageType As String)
        Dim expectedBaudRate As String = "57600"
        Select Case gageType
            Case "DSI"
                AddHandler dataBackgroundWorker.DoWork, AddressOf DoDualDSIWorkCOM1
                AddHandler dataBackgroundWorker.RunWorkerCompleted, AddressOf DualDSIWorkComplete
                expectedBaudRate = "9600"
              
        End Select
        currentSerial = GetSerialPortUsed(1)
        currentSerial2 = GetSerialPortUsedCOM2(2)
        ChangeCOMBaudRateIfNecessary(expectedBaudRate)
        dataBackgroundWorker.RunWorkerAsync(New Object() (currentSerial})
        dataBackgroundWorker2.RunWorkerAsync(New Object() {currentSerial2})
        Me.tmrBackgroundWorker.Enabled = True
        Me.tmrBackgroundWorker2.Enabled = True
 
 
 
 
Private Sub DoDualDSIWorkCOM1(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Try
            Dim args() As Object = e.Argument
            Dim intloop As Integer
            CType(args(0), IO.Ports.SerialPort).DiscardInBuffer()
            muxClass.GetDualDSIInputCOM1(CType(args(0), IO.Ports.SerialPort))
        Catch ex As Exception
            tListener.AddMethodError(ex)
        End Try
    End Sub
 
 
 
Public Sub GetDualDSIInputCOM1(ByVal serialPort As IO.Ports.SerialPort)
        Dim intloop As Integer
        Try
            serialPort.ReadTimeout = 500
            serialPort.DiscardInBuffer()
 
            Dim strDataCOM1 As String = String.Empty
            If Not serialPort.IsOpen Then
                strDataCOM1 = String.Empty
            Else
                strDataCOM1 = serialPort.ReadLine
            End If
            If strDataCOM1.Length > 0 Then
                COM1Active = 1
                Dim tempArray() As String
                strDataCOM1 = strDataCOM1.Replace(vbCrLf, vbTab).Replace(Chr(26), "").Replace(Chr(12), "").Replace(Chr(13), "")
                'parses out the information gathered from the COM port to a temp location
                tempArray = Split(strDataCOM1, vbTab)
 
                If serialPort.BaudRate = 9600 Then
                    DSICollector = "585 Plus"
                    Get585PlusData(tempArray)
                Else
                    DSICollector = "501/440"
                    Get501Data(tempArray)
                End If
            End If
 
        Catch tex As TimeoutException
            'do nothing as this will happen while waiting
        Catch ioError As System.IO.IOException
            'do nothing as this will occur sometimes when closing the thread
        Catch ex As Exception
            tListener.AddMethodError(ex)
        End Try
    End Sub

Open in new window

0
Comment
Question by:cmdolcet
  • 5
  • 3
8 Comments
 
LVL 19

Expert Comment

by:drichards
ID: 22845480
You have provided only bits and pieces of the code (second background worker has no function, for example), and only a general statement that you want to synchronize threads.  What exactly are you trying to synchronize?  There are events and delegates if you want to signal thread activity, and there are mutexes if you want to prevent the two threads from simultaneously accessing a shared resource.
0
 

Author Comment

by:cmdolcet
ID: 22849243
The problem is that the second background worker has the exact same code except it will look at COM 2 on the PC. What goes on is this in the DoDualDSIWorkCOM1 my backgroundworker2 passes in COM 2 and then it passes the serial COM port into the getDualDSIInputCOM1 Sub. What i notice is that regardless you have no control over backgroundworkers and sometimes it passes in COM 1 6 times and other times it passes in COM2

The issues is this. I need to have both COM 1 and COM2 be passed in the DoDualDSIWorkCOM1 so that when a user takes readings on either com I can see them populate in the runtime side at the same time.
Private Sub DoDualDSIWorkCOM1(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Try
            Dim args() As Object = e.Argument
            Dim intloop As Integer
            CType(args(0), IO.Ports.SerialPort).DiscardInBuffer()
            muxClass.GetDualDSIInputCOM1(CType(args(0), IO.Ports.SerialPort))
        Catch ex As Exception
            tListener.AddMethodError(ex)
        End Try
    End Sub
 
 
 
Public Sub GetDualDSIInputCOM1(ByVal serialPort As IO.Ports.SerialPort)
        Dim intloop As Integer
        Try
            serialPort.ReadTimeout = 500
            serialPort.DiscardInBuffer()
 
            Dim strDataCOM1 As String = String.Empty
            If Not serialPort.IsOpen Then
                strDataCOM1 = String.Empty
            Else
                strDataCOM1 = serialPort.ReadLine
            End If
            If strDataCOM1.Length > 0 Then
                COM1Active = 1
                Dim tempArray() As String
                strDataCOM1 = strDataCOM1.Replace(vbCrLf, vbTab).Replace(Chr(26), "").Replace(Chr(12), "").Replace(Chr(13), "")
                'parses out the information gathered from the COM port to a temp location
                tempArray = Split(strDataCOM1, vbTab)
 
                If serialPort.BaudRate = 9600 Then
                    DSICollector = "585 Plus"
                    Get585PlusData(tempArray)
                Else
                    DSICollector = "501/440"
                    Get501Data(tempArray)
                End If
            End If
 
        Catch tex As TimeoutException
            'do nothing as this will happen while waiting
        Catch ioError As System.IO.IOException
            'do nothing as this will occur sometimes when closing the thread
        Catch ex As Exception
            tListener.AddMethodError(ex)
        End Try
    End Sub

Open in new window

0
 
LVL 19

Expert Comment

by:drichards
ID: 22849703
Am I missing something or are you creating new worker threads every time you want data from the serial ports?  I don't see any loops inside DoDualDSIWorkCOM1 or GetDualDSIInputCOM1 (both of which I would rename since neither is specific to COM1).

If the latter is true you should redesign the code anyway.  Based on the code I see, synchromization would not go in the thread code but somewhere outside.

If data is arriving on COM1 6 times faster than on COM2, shouldn't COM1 be processed 6 times as often?

With the answers to these quesions I should be able to tell you how to solve your problem.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:cmdolcet
ID: 22849902
Ok I will attache all the code in a file. This all I have I hope this helps....Its so urgent
Public-Sub-StartWorkerThreadDual.doc
0
 
LVL 19

Expert Comment

by:drichards
ID: 22855865
The code isn't what I need.  I need to know what it is you are trying to synchronize.  I also don't see what initiates a read of the serial port.  And as far as the code I do see, it looks like you start up a thread EVERY time you want to read a serial port, which is REALLY bad.  The threads should just be in a loop and you signal them to do a read.  The thread can just wait in between reads.

I'd change the code to handle OnData events from the serial ports and just do a port.ReadLine in the handler and forget about worker threads.  From what I see, you don't need worker threads at all.
0
 

Author Comment

by:cmdolcet
ID: 22866745
I need to be able to take reading from an IO device say a hand held data collector  at the same time. when I hit the send button on both IO devices it should populate the boxes at the same time.
0
 
LVL 19

Expert Comment

by:drichards
ID: 22868412
Then I believe my last comment is what you want.  Just handle OnData events from the devices and you will be notified when data is available.  You can then go read the data and populate the boxes, whatever those are.  If you send data from multiple devices simultaneously, the events will all fire at the same time and the boxes should get populated at the same time.  If you send a lot of data from one device and none from the second, onle the one will update.
0
 
LVL 19

Accepted Solution

by:
drichards earned 500 total points
ID: 22868420
Technically, the OnData events are from the serial ports, not from the devices.
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

Suggested Solutions

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

773 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