Всем здравствуйте! Давненько просил помощи в решении многопоточности, диалог с форумчанами не вышел, приношу свои извинения Эросу и остальным, так как его замечания были жесткими, но справедливыми, на, что я грубо ответил.
Собственно вопрос, имеются два прибора, которые нужно опрашивать все время провидения испытания, решил потихоньку переходить на вб.нет )). Использую контрол 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-ы ???
Ответить
|