我目前正在编写一个通过串行连接与集成伺服系统通信的应用程序。
电机以高达 1000 次/秒的速率发出位置数据。我想要实现的是能够格式化返回的数据(通过去除空格、换行等)并解析它以从接收到的字符串中提取相关数据。
目前,我让数据接收事件处理程序读取数据,使用一系列 string.replace 方法调用对其进行格式化,并将其附加到充当缓冲区的字符串。然后,使用线程,我不断地检查缓冲区,因为它填充了一个特定的分隔符(在我的例子中是“\r”),它表示来自电机的一条消息的结尾,然后从缓冲区中删除该消息并将其打印到一个 rich文本字段。
这种方法有两个问题。一是因为电机以如此高的速率传输位置数据,缓冲区填充速度快于线程处理数据的速度。因此,当我向电机发送命令时,它会立即 Action ,但响应会延迟几秒钟,因为必须首先处理缓冲区中的所有先前数据。其次,让两个线程运行一个实现 while(true) 结构的方法意味着处理器利用率飙升,并且在几秒钟内 pc 中的风扇就达到最大。
是否有更好的数据处理方式?
这是我的事件处理程序代码:
//data recieved event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//cut out any unnecessary characters
tmp = tmp.Replace("\n", "");
tmp = tmp.Replace(",", "\r");
tmp = tmp.Replace(" ", "");
lock (this)
{
//put all received data into the read buffer
readBuffer += tmp;
}
}
线程执行的方法如下:
private void parseBuffer()
{
while (true)
{
//obtain lock, parse one message from buffer
lock (this)
{
if (readBuffer.IndexOf("\r") > 0)
{
String t = readBuffer.Substring(0, readBuffer.IndexOf("\r") + 1);
readBuffer = readBuffer.Replace(t, "");
dataReady(this, new CustomEventArgs(t, null));
}
}
}
}
最佳答案
即使自上次尝试以来没有新数据,您的 parseBuffer
也会疯狂旋转。
您可以通过信号来缓解这种情况。
private AutoResetEvent waitHandle = new AutoResetEvent(false);
触发dataReceived
中的信号
//data recieved event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//cut out any unnecessary characters
tmp = tmp.Replace("\n", "");
tmp = tmp.Replace(",", "\r");
tmp = tmp.Replace(" ", "");
lock (this)
{
//put all received data into the read buffer
readBuffer += tmp;
waitHandle.Set(); // <-- tell parseBuffer that new data is available
}
}
等待parseBuffer
中的信号
private void parseBuffer()
{
while (true)
{
waitHandle.WaitOne(); // <-- waits until there is more data to parse
//obtain lock, parse one message from buffer
lock (this)
{
if (readBuffer.IndexOf("\r") > 0)
{
String t = readBuffer.Substring(0, readBuffer.IndexOf("\r") + 1);
readBuffer = readBuffer.Replace(t, "");
dataReady(this, new CustomEventArgs(t, null));
}
}
}
}
关于c# - 最快的多线程解析串口数据的方法C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5993644/