Всем здравствуйте! Давненько просил помощи в решении многопоточности, диалог с форумчанами не вышел, приношу свои извинения Эросу и остальным, так как его замечания были жесткими, но справедливыми, на, что я грубо ответил.
 
 
Собственно вопрос, имеются два прибора, которые нужно опрашивать все время провидения испытания, решил потихоньку переходить на вб.нет )). Использую контрол SerialPort, Read_H_Q (таймер) - для отправки команд в порты, таймеры TimeOut_Rate и TimeOut_Compres - так сказать сторожевые таймеры, если по какой-то причине DataReceived портов не возникали отправляю, новую посылку в порт. Ну и таймер сбора данных, который, отображает, записывает и т.д. полученные данные.
 
 
Пример:
 
Private Sub Read_H_Q_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Read_H_Q.Tick
 
 
        If start_rate = True Then
 
            Com_Rate.DiscardInBuffer()
 
            Com_Rate.DiscardOutBuffer()
 
 
            Dim data As [Byte]() = System.Text.Encoding.Default.GetBytes(Chr(&H1) + Chr(&H4) + Chr(&HC0) + Chr(&H8) + Chr(&H0) + Chr(&H2) + Chr(&HCC) + Chr(&H9))
 
            Com_Rate.Write(data, 0, data.Length)
 
            start_rate = False
 
 
            TimeOut_Rate.Interval = 500
 
            TimeOut_Rate.Start()
 
        End If
 
 
        If start_cump = True Then
 
            Com_Compression.DiscardInBuffer()
 
            Com_Compression.DiscardOutBuffer()
 
 
            Dim data As [Byte]() = System.Text.Encoding.Default.GetBytes(("#01") + Chr(&HD))
 
            Com_Compression.Write(data, 0, data.Length)
 
            start_cump = False
 
 
            TimeOut_Rate.Interval = 500
 
            TimeOut_Compres.Start()
 
        End If
 
 
    End Sub 
 
    Private Sub TimeOut_Rate_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimeOut_Rate.Tick
 
        start_rate = True
 
        TimeOut_Rate.Stop()
 
    End Sub
 
 
    Private Sub TimeOut_Compres_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimeOut_Compres.Tick
 
        start_cump = True
 
        TimeOut_Compres.Stop()
 
    End Sub 
 
    Private Sub Com_Compression_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Com_Compression.DataReceived
 
        Try
 
            TimeOut_Compres.Stop()
 
 
            Dim bytes As Int32
 
            Dim data As [Byte]()
 
 
            data = New [Byte](14) {}
 
            Do While data(14) = 0
 
                bytes = Com_Compression.Read(data, 0, data.Length)
 
            Loop
 
 
            If data(0) <> 62 Or data(1) <> 62 Then start_cump = True : Exit Sub
 
 
            Dim otvet As String = ""
 
            For i = 2 To data.Length - 1
 
                If data(1) <> 62 Then otvet = otvet & Chr(data(i)) Else otvet = otvet & Chr(data(i + 1))
 
            Next
 
 
            P1_test = Math.Round(CSng(((Replace(Strings.Left(otvet, 6), ".", ",") * 1) - 4) * 1), 2) '7.903420523
 
            P2_test = Math.Round(CSng(((Replace(Strings.Right(otvet, 6), ".", ",") * 1) - 4) * 9.82), 2) '7.903420523
 
        Catch ex As Exception
 
          MsgBox(ex.Message)
 
        End Try
 
 
        start_cump = True
 
    End Sub 
 
    Private Sub Com_Rate_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Com_Rate.DataReceived
 
        Try
 
            TimeOut_Rate.Stop()
 
 
            Dim bytes As Int32
 
            Dim data As [Byte]()
 
 
            data = New [Byte](8) {}
 
            Do While data(8) = 0 Or data(7) = 0
 
                bytes = Com_Rate.Read(data, 0, data.Length)
 
            Loop
 
 
            Dim Otv_BYTE(3) As Byte
 
            For F = 0 To 3
 
                Otv_BYTE(3 - F) = data(F + 3)
 
            Next
 
 
            Q_test = Math.Round((BitConverter.ToSingle(Otv_BYTE, 0) * 1.44) * (2910 / Freq), 2) 'Math.Round(BitConverter.ToSingle(Otv_BYTE, 0) * 1.44, 2)
 
        Catch ex As Exception
 
            MsgBox(ex.Message)
 
        End Try
 
        start_rate = True
 
    End Sub 
 
 
есть ещё таймер Read_M20C, для работы с бблиотекой в потоке
 
Private Sub Read_M20C_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Read_M20C.Tick
 
        If Started = False Then Started = True Else Exit Sub
 
        BackgroundWorker1.RunWorkerAsync()
 
    End Sub
 
 
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
 
        Dim err As String = "0"
 
        Dim num As Long
 
        num = M20C.ReadItem(SENSOR, SensorDataCopy, err)
 
    End Sub
 
 
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
 
        If SensorDataCopy.Moment < 0 Then Moment = Math.Round((((5 * SensorDataCopy.Moment * 0.1) / 3.837) * (-1)) - 8.39, 2) Else Moment = Math.Round(((5 * SensorDataCopy.Moment * 0.1) / 3.837) - 8.39, 2)
 
        Freq = Math.Round(SensorDataCopy.Frequency, 0)
 
        Temp_M20C = SensorDataCopy.Temperature
 
        Power = Math.Round((CSng(Moment) / 10) * CSng(Freq) / 955 * ((2910 / Freq) * (2910 / Freq) * (2910 / Freq)), 2)
 
        Started = False
 
    End Sub 
 
 
В Com_Rate мы читаем показания расхода, так вот почему-то переодически считывание останавливается, флаг start_rate не получает значение true, если убрать это подобие синхронизации посылки-ответа, то возникает ошибка переполнения стека неизвестного модуля. Писать догадки пока не буду интересно ваши соображиния, может я не верно обрабатываю DataReceived-ы ???
Ответить
        |