iso*_*rik 7 c# parsing serial-port
我目前正在编写一个通过串行连接与集成伺服器通信的应用程序.
电机以高达1000次/秒的速率发送位置数据.我想要实现的是能够格式化返回的数据(通过剥离空格,新行等)并解析它以从接收的字符串中提取相关数据.
目前,我有数据接收事件处理程序读取数据,使用一系列string.replace方法调用格式化它,并将其附加到充当缓冲区的字符串.然后,使用线程,我不断检查缓冲区,因为它填充特定的分隔符(在我的情况下为"\ r"),表示来自电机的一条消息的结束,然后从缓冲区中删除该消息并将其打印到富有文本域.
这种方法存在两个问题.一个是因为电机以如此高的速率传输位置数据,所以缓冲器填充的速度比线程可以处理的数据快.因此,当我向电机发送命令时,它会立即动作,但响应会延迟几秒钟,因为必须首先处理缓冲区中的所有前面的数据.其次,让两个线程运行一个实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是线程执行的方法:
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));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说,我会在仅从套接字读取的读取器线程和解析线程之间使用阻塞集合。
在性能方面,考虑使用 split 进行解析 - 这比在字符串内替换要快得多。您应该考虑使用正则表达式和/或 StringBuilder 类 - 您应该使用 1 个带有替代项的表达式 正则
表达式代码如下所示:
string pattern = " |\\n|\\r";
string replacement = " ";
regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);
Run Code Online (Sandbox Code Playgroud)