问题
从串口我收到一个字符流。我收到的流将被 \n 终止。我以如下方式接收串行端口数据:
Serial port Event 1: "123\n456\n789"
Serial port Event 2: "\n0123\n456\n789\n"
Serial port Event 3: "0123\n456\n789\n"
如您所见,我的流在波动,这是非常正常的,因为我使用“当前可用的内容”读取串行端口。
我的问题是我想用 RichTextBox 将它记录到 UI 中。我不能使用 ListBox,因为我需要颜色和字体格式。
第一种方法
在我在下面尝试这个之前,效果很好,直到消息超过大约 30.000 行文本。UI 变得无响应。这是代码:
uiTextActivity.SelectionFont = new Font(uiTextActivity.SelectionFont, FontStyle.Bold);
uiTextActivity.SelectionColor = LogMsgTypeColor[(int)msgtype];
uiTextActivity.AppendText(msg);
uiTextActivity.ScrollToCaret();
后来我用它作为一个快速修复,在 2000 行之后清除该框:
if ((int.Parse(uiLabelCounterActivity.Text) + 1) > 2000)
uiTextBoxResetActivity();
我想保留大约 500 行的历史记录。但是通过上面的这个快速修复,当计数器达到 2000 时,我完全丢失了我的日志。
我想我需要的是一个圆形的 FIFO 文本框。所以我可以在 500 行之后删除最旧的日志并附加新的日志。
第二种方法
我也试过这个(请注意,在这种情况下,最新的日志条目位于顶部,文本框中最旧的条目位于下方)
msg = msgToPasteWhenComplete + msg;
int c = 0; // c=zero if no newline, 1 for single newline, 2 for 2times newline and so on
int latestTermination = 0;// store the point where \n is found
for (int e = 0; e < msg.Length; e++)
{
if (msg[e] == '\n')
{
c++;
latestTermination = e+1;
}
}
// contains strings all terminated with \n
string msgToPaste = msg.Substring(0, latestTermination);
// contains string that is not complete (not yet terminated with \n)
msgToPasteWhenComplete = msg.Substring(latestTermination, msg.Length - latestTermination);
string previous = msgToPaste + uiTextActivity.Text;
if (previous.Length > maxDisplayTextLength)
{
string debugInfo3 = previous.Substring(0, maxDisplayTextLength);
uiTextActivity.Text = debugInfo3;
}
else
uiTextActivity.Text = previous;
这几乎可以很好地工作。这种方法的问题是来自串行端口的行在收到 \n 之前不会被粘贴到 UI。这意味着每当通信缓慢时,我必须等待串行流完成包括 \n 在内的整行才能看到它......我想要的是直接看到每个字符。
关于串口的信息
我从 SerialDataReceivedEvent 获得的串行数据,在这种情况下,我使用 comport.ReadExisting() 来进行非阻塞事件。串行数据来自我的具有模拟读数的嵌入式编程板。模拟读数每秒为我提供 20 行,每行包含 20 个字符。我需要在用户界面中读取原始数据,其中必须根据串行消息的前缀将其过滤到其他文本框(例如 err 进入 error , warn 进入警告文本框,但它们都进入活动日志. 活动日志就是这个问题的内容。