C# 正在尝试将密集的传入串行数据打印到richtextbox中
我正在开发一个基于arduino串行监视器的串行监视器项目,但是有更多的功能 有两个基本功能-读取串行数据和将其可视化到richtextbox,写入串行数据,以及将其可视化到richtextbox。当通信非常密集(arduino尽可能快地发送一条线路)并且用户输入将一些接收到的线路切成两半时,就会出现问题。我做了一个算法,通过设置发送/接收标志将richtextbox中的输入字符串与输出字符串分开。然而,这让这个节目显得很奇怪。有时,发送给arduino的命令在richtextbox中不会显示,但来自arduino的数据显示良好。我尝试在用户输入可视化方法上设置断点,但很少被激活。更重要的是,我还在读取数据方法的可视化上设置断点,它们也很少被激活。然而,表单没有延迟或冻结,命令在richtextbox中飞行,这与观察到的断点行为相反。打印算法很繁重,因为我实现了多色打印 我的尝试:C# 正在尝试将密集的传入串行数据打印到richtextbox中,c#,arduino,serial-port,richtextbox,C#,Arduino,Serial Port,Richtextbox,我正在开发一个基于arduino串行监视器的串行监视器项目,但是有更多的功能 有两个基本功能-读取串行数据和将其可视化到richtextbox,写入串行数据,以及将其可视化到richtextbox。当通信非常密集(arduino尽可能快地发送一条线路)并且用户输入将一些接收到的线路切成两半时,就会出现问题。我做了一个算法,通过设置发送/接收标志将richtextbox中的输入字符串与输出字符串分开。然而,这让这个节目显得很奇怪。有时,发送给arduino的命令在richtextbox中不会显示,
void printToConsole(string print, Color txtColor, string part, Color partColor, bool isMsg, bool endNL)
{
while (print.Contains('\r'))
print = print.Replace("\r", "");
for (int i = 0; i < print.Length; i++)
{
if (newString)
{
newString = false;
printTimeAndPart(part, partColor);
}
else if (i == 0 && !prevStrHadNL && isMsg != prevWasMsg)
{
printNLTimeAndPart(part, partColor);
}
else if (i == 0 && prevStrHadNL)
{
printNLTimeAndPart(part, partColor);
}
else if (i == print.Length - 1)
{
if (print[i] == '\n')
{
if (endNL && isMsg != prevWasMsg)
AppendText("\n");
prevStrHadNL = true;
break;
}
else
{
if (endNL)
AppendText("\n");
prevStrHadNL = false;
}
}
if (print[i] == '\n')
{
printNLTimeAndPart(part, partColor);
}
else
AppendText(print[i].ToString(), txtColor);
}
prevWasMsg = isMsg;
}
private void printNLTimeAndPart(string part, Color partColor)
{
AppendText("\n");
printTimeAndPart(part, partColor);
}
private void printTimeAndPart(string part, Color partColor)
{
if (timestamp == 1)
AppendText(DateTime.Now.ToString("HH:mm:ss.fff"), timeColor);
AppendText(part, partColor);
}
private void AppendText(string txt, Color clr)
{
if (serialControl.ReadAllowed)
{
if (rtArea.InvokeRequired)
{
MethodInvoker mi = delegate ()
{ rtArea.AppendText(txt, clr); };
Invoke(mi);
}
else
rtArea.AppendText(txt, clr);
}
}
private void AppendText(string txt)
{
if (serialControl.ReadAllowed)
{
if (rtArea.InvokeRequired)
{
MethodInvoker mi = delegate ()
{ rtArea.AppendText(txt); };
Invoke(mi);
}
else
rtArea.AppendText(txt);
}
}
-尝试了blockingcollection方法。只需将打印操作放入队列中,并使用主线程的2个附加线程逐个执行操作。(Task.Factory.StartNew)。问题是队列在一分钟内就被3000多个动作填满,整个过程落后了15秒左右
-我尝试启动一个新的Task.Factory for every receive/send方法用于每次打印新命令,并锁定线程,直到命令打印到richtextbox中。这也太慢了
最后我想到了只设置标志并允许或不允许打印事件的想法。使用这种方法,用户输入几乎从不打印在richtextbox中:(
打印算法:
void printToConsole(string print, Color txtColor, string part, Color partColor, bool isMsg, bool endNL)
{
while (print.Contains('\r'))
print = print.Replace("\r", "");
for (int i = 0; i < print.Length; i++)
{
if (newString)
{
newString = false;
printTimeAndPart(part, partColor);
}
else if (i == 0 && !prevStrHadNL && isMsg != prevWasMsg)
{
printNLTimeAndPart(part, partColor);
}
else if (i == 0 && prevStrHadNL)
{
printNLTimeAndPart(part, partColor);
}
else if (i == print.Length - 1)
{
if (print[i] == '\n')
{
if (endNL && isMsg != prevWasMsg)
AppendText("\n");
prevStrHadNL = true;
break;
}
else
{
if (endNL)
AppendText("\n");
prevStrHadNL = false;
}
}
if (print[i] == '\n')
{
printNLTimeAndPart(part, partColor);
}
else
AppendText(print[i].ToString(), txtColor);
}
prevWasMsg = isMsg;
}
private void printNLTimeAndPart(string part, Color partColor)
{
AppendText("\n");
printTimeAndPart(part, partColor);
}
private void printTimeAndPart(string part, Color partColor)
{
if (timestamp == 1)
AppendText(DateTime.Now.ToString("HH:mm:ss.fff"), timeColor);
AppendText(part, partColor);
}
private void AppendText(string txt, Color clr)
{
if (serialControl.ReadAllowed)
{
if (rtArea.InvokeRequired)
{
MethodInvoker mi = delegate ()
{ rtArea.AppendText(txt, clr); };
Invoke(mi);
}
else
rtArea.AppendText(txt, clr);
}
}
private void AppendText(string txt)
{
if (serialControl.ReadAllowed)
{
if (rtArea.InvokeRequired)
{
MethodInvoker mi = delegate ()
{ rtArea.AppendText(txt); };
Invoke(mi);
}
else
rtArea.AppendText(txt);
}
}
这是我的串行控制器类中的dataReceived方法:
我尝试了几种读取串行数据的方法,未注释的方法是我尝试过的最稳定的方法
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
/* byte[] buffer = new byte[blockLimit];
Action kickoffRead = null;
kickoffRead = delegate
{
port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
{
try
{
int actualLength = port.BaseStream.EndRead(ar);
byte[] received = new byte[actualLength];
Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
string rcv = Encoding.Default.GetString(received);
dataRecieved(rcv);
}
catch (IOException exc)
{
//handleAppSerialError(exc);
}
kickoffRead();
}, null);
};
kickoffRead();
*/
if (ReadAllowed)
{
string a = port.ReadExisting();
//port.DiscardInBuffer();
dataRecieved(a); //Raise event and pass the string to Form1 serial_dataReceived
}
}
因此,我需要一些关于如何准确打印多色消息的建议,而不相互切割,每次打印速度快,cpu负载低(现在i5-4310m上的满负载率为35%(arduino密集型传输)。如果您也能提供一些示例,我将非常高兴