将事件与c#中的串行端口结合使用



我正在构建一个net6.0应用程序,在该应用程序中,我们必须与通过RS232串行端口进行通信的外部设备进行交互。

外部设备使用协议与应用程序通信,其中我们事先知道消息包的大小和某些部分(标头,如(,并且基于客户端-服务器架构

在我尝试实现该解决方案时,我在串行的无限while循环中使用了轮询,该循环运行良好,尽管同步需要相当长的时间(大约30秒(。

我试图绕过这个解决方案事件驱动的方法";基于事件并尝试通过DataReceived事件读取数据。

虽然我似乎正在取回数据,但缓冲区的实际内容与预期的明显不同,大小要大得多(预计最大值约为10-15字节,实际值约为140字节(。

我阅读了提供的第二个链接上的评论,似乎有一些模棱两可的结果:

  1. 操作系统决定何时引发事件
  2. 每个字节到达时不会引发事件

我的问题是:

  1. 何时触发DataReceived事件?操作系统是否会缓冲接收到的数据并将其作为一批数据发送?例如;请求";来自RS232的数据将是12个字节,下一个是14个字节等,因此当我试图从缓冲区访问数据时,会有更多的字节?

  2. 是否有一种方法可以配置应用程序或操作系统(不确定该解决方案的便携性(,以便当RS232设备发送任何类型的有效载荷(例如12字节或14字节等(时,这将明确触发事件?

非常感谢您抽出时间!

您想要的可能是:

使用BytesToRead属性可以确定缓冲区中还有多少数据需要读取。当客户端发送EOC字符时,DataRecived事件通常会触发。当足够的字节出现在";BytesToRead";。有时它会为每个字节触发。

Private Sub _SerialPortReader_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles _SerialPortReader.DataReceived
Dim currentSP As SerialPort = Convert.ChangeType(sender, GetType(SerialPort))
Dim strBuilder As System.Text.StringBuilder = New System.Text.StringBuilder()
Dim incomingText As String = ""
currentSP.ReadTimeout = 1000
Do
Try
strBuilder.Append(Convert.ChangeType(currentSP.ReadByte(), GetType(Char)))
incomingText = strBuilder.ToString()
If incomingText.Contains(CustomSharedFunctions.GetStringFromDecimal(_EndofCommunicationString)) Then Exit Do
Catch ex As Exception
Exit Do
End Try
Loop
'incomingText contains now the full message sent to you, remember this event triggers on a different thread, so you might want to use Invoke() here.
End Sub

这里的C#代码:

private void _SerialPortReader_DataReceived(object sender, SerialDataReceivedEventArgs e){
SerialPort currentSP = Convert.ChangeType(sender, typeof(SerialPort));
System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
string incomingText = "";
currentSP.ReadTimeout = 1000;
do
{
try
{
strBuilder.Append(Convert.ChangeType(currentSP.ReadByte(), typeof(char)));
incomingText = strBuilder.ToString();
if (incomingText.Contains(CustomSharedFunctions.GetStringFromDecimal(_EndofCommunicationString)))
break;
}
catch (Exception ex)
{
break;
}
}
while (true);}

也许你不应该关心操作系统如何/何时管理它的东西。。。通常,它是由缓冲区大小/性能超时之间的微妙平衡触发的。

据我所知,您正在应用程序级别工作,因此您可能更应该专注于检测帧的末尾(因为您使用的是给定的协议(,而不是单个字节。

我建议尝试在传入数据上构建一种解析器/适配器,以检测格式良好/分离的帧(在专用/自定义事件中,是否优雅/健壮?(。。。

协议只是嵌套层/帧到位/字节的问题。。。

最新更新