我有一个程序,它创建数据包并将它们放入一个队列中,并使用一个单独的线程检查队列,如果有数据,它通过串行连接发送它,否则它会等待一点并再次检查。问题是如果我一次发送太多数据然后不响应,我发送的设备将不堪重负。为了解决这个问题,我需要让我的传输线程等到我从设备收到一个完整的数据包,所以在DataReceived事件中我检查我是否收到了整个数据包,如果有,它会被解析,我想发信号通知发送线程可以发送另一个数据包,否则,我想等待其余的数据,而不用发信号通知发送线程。
这是我的传输线程
Private Sub TxThread()
While Not abortThread
While (Not abortThread) AndAlso (txQueue.Count = 0)
Thread.Sleep(500)
End While
mPort.SendCommand(txQueue.Dequeue())
''''
'''' Wait for signal that entire packet received
''''
End While
End Sub
这是我的DataReceived
Private Sub mPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles mPort.DataReceived
' Checks to see if enough data has been received to check for the Preamble
If mPort.BytesToRead >= 2 And mPort.IsOpen Then
' Stores the string received into the packet variable
packet &= mPort.ReadExisting()
' Checks to see if the string starts with the correct preamble
If packet.StartsWith(ToCharacters(CommandStringBuilder.PREAMBLE)) Then
PreambleReceived()
ElseIf packet.Contains(ToCharacters(CommandStringBuilder.PREAMBLE)) Then
' If the data doesn't start with a preamble but it contains one, then it cuts off everything before the preamble and
' checks to see if it is long enough to get the length byte
packet = packet.Remove(0, packet.IndexOf(ToCharacters(CommandStringBuilder.PREAMBLE)))
' If it is long enough, then it checks if it has the whole string using the length byte and the actual length
PreambleReceived()
Else
' If the data doesn't contain the preamble then discard the string and reset rxData
packet = ""
End If
End If
End Sub
Private Sub PreambleReceived()
' If the string is long enough, check the length byte in the string
If packet.Length > 8 Then
' Calls a function I defined to test the number of bytes I received vs the number of bytes I expect and returns the difference
Dim bytesEqual As Byte = GetBytesReceived()
' If the length byte and the actual length match, then the entire string has been received and can be sent for parsing
If bytesEqual = 0 Then
''''
'''' Signal entire packet received
''''
packet = ""
' If the actual length is greater than the bytes expected then check to see if the string contains another preamble
' and if it does, cut off and discard everything after and including the second preamble, if not then it discards the data
ElseIf bytesEqual < 0 Then
If packet.Substring(3).Contains(ToCharacters(CommandStringBuilder.PREAMBLE)) Then
Dim receivedTextBuffer As String
Dim startIndex As Integer = packet.IndexOf(ToCharacters(CommandStringBuilder.PREAMBLE), 3)
' Gets the index of the preamble starting at index 3 and removes it and everything after it
receivedTextBuffer = packet.Substring(startIndex)
packet = packet.Remove(startIndex)
''''
'''' Signal entire packet received
''''
packet = receivedTextBuffer
Else
' If packet doesn't contain a preamble, then discard the data and reset
packet = ""
End If
' If the bytes expected > bytes received then exit without resetting anything and wait for more data
End If
' If the length isn't long enough to see the length byte yet, exit without resetting anything and wait for more data
End If
End Sub
值得注意的是,TxThread和带有PreambleReceived的DataReceived位于不同的类中,因此TxThread中的mPort与DataReceived中的mPort不同。