运行tool时发现串口data 丢失,最后找到源头是serialPort1.ReadBufferSize的大小设置不合适。之间值为1024*16 。因为之后对log进行了较为复杂的处理,耗时较长,导致接收缓冲区过载。造成log丢失
代码中处理data receive 的逻辑是
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。
//
// 返回结果:
// 如果该操作成功,则为 true;否则为 false。
receivedEvent.Set();
}
private void backgroundWorker_Log_DoWork(object sender, DoWorkEventArgs e)
{
do
{
receivedEvent.WaitOne();
rxdata();
update_line_number(is_at_max_scroll);
} while (true);
}
if (serialPort1.IsOpen == false)
{
try
{
if (!backgroundWorker_Log.IsBusy)
backgroundWorker_Log.RunWorkerAsync();
...
}}}
private void backgroundWorker_Log_DoWork(object sender, DoWorkEventArgs e)
{
do
{
// waitOne 阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号。
receivedEvent.WaitOne();
rxdata();
update_line_number(is_at_max_scroll);
} while (true);
}
AutoResetEvent: 通知正在等待的线程已发生事件。 此类不能被继承。 串口打开,backgroundWorker_Log_DoWork 启动,此时receivedEvent.WaitOne();阻塞进程,serialPort1_DataReceived接收数据被触发时,进入rxdata事件,rxdata中进行数据处理
try
{
while (serialPort1.BytesToRead != 0)
{
is_at_max_scroll = IsAtMaxScroll();
readLength = serialPort1.Read(rawDataBuffer, 0, bufferSize);
// if read length is smaller than 4096, then use the actual number of rawDataBuffer.
byte[] actualData = new byte[readLength];
Buffer.BlockCopy(rawDataBuffer, 0, actualData, 0, readLength);
decodeAGGflow(actualData);
}
if(logContainer.Length != 0)
{
ShowAndSaveLog();
}
}
serialPort1.BytesToRead 不为0的时候, 从 System.IO.Ports.SerialPort 输入缓冲区读取一些4096并将那些字节写入字节数组中rawdatabuffer中进行处理。