Link to home
Start Free TrialLog in
Avatar of cmdolcet
cmdolcetFlag for United States of America

asked on

How to _synchronize_ two threads

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

Avatar of drichards
drichards

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.
Avatar of cmdolcet

ASKER

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

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.
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
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.
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.
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.
ASKER CERTIFIED SOLUTION
Avatar of drichards
drichards

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial