串口接收数据与鼠标移动事件冲突怎么办
我在C#中用serialport控件实现了一个串口小程序,具体如下:1.该程序每100ms发出一个命令给外部接收设备,由一个timer控制
2.设置串口接收的ReceivedBytesThreshold为1,即每接收到一个字节就触发DataReceive事件,DataReceive事件代码如下:
public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
long lExecuteTime = 0;
// modified trigger condition to maximum time
serialPort1.ReceivedBytesThreshold = serialPort1.ReadBufferSize;
int curbyte = serialPort1.ReadByte();
recvbuf[iCurPos++] = (byte)curbyte;
if (curbyte == 0x7E) // received a completed response
{
EndTime = DateTime.UtcNow;
timer_timeout.Enabled = false;
lExecuteTime = (EndTime.Ticks - StartTime.Ticks) / 10; // change to us
lb_time.Text = lExecuteTime.ToString() + " us";
InforDisplay(recvbuf, iCurPos);
iCurPos = 0;
}
else if (iCurPos > 79)
{
txtBox_Err.Text += "Error: Receive buffer over flow!\r\n";
iCurPos = 0;
}
// recover trigger condition to 1
serialPort1.ReceivedBytesThreshold = 1;
}
这其中调用了一个函数InfoDisplay, 这个函数用来将接收到的数据显示到界面上。
3. 问题:程序运行之后,命令收发正常,显示也正常;但是当鼠标在窗体上移动时,串口数据就会有丢失的可能,鼠标移动的越快,出错几率越大。我推断,鼠标移动时,程序要响应mousemove事件(我并没有处理这个事件),导致来不及响应datareceive事件,造成数据丢失
4. 从网上查,用多线程可以解决这个问题,但是我不知道该怎么设计这个多线程,请大家指点
多谢 串口 接收数据 鼠标移动 多线程 C# --------------------编程问答-------------------- 进一步的测试,只要是鼠标移动,无论在不在这个窗体上,都会对串口接收数据造成影响。或者说,只要是操作了本台PC上的任何其他程序,都会对串口接收造成影响! --------------------编程问答-------------------- 代码没有,怎么分析? --------------------编程问答--------------------
http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport.datareceived.aspx
你的响应函数每次只读一个字节,是可能会"丢失数据"。
建议按照MSDN的方法进行改进。 --------------------编程问答-------------------- 其实这个和你鼠标没有任何关系,这样使用是一定有问题的。
接收事件里不要做处理,只接收就好了,接收事件中有比较耗时的处理逻辑都会导致丢数据。处理要另开线程。具体原因不清楚,我觉得使用事件接收后,串口软件缓冲都无效了,无论设置多大的缓冲,都会丢数据。
txtBox_Err.Text += "Error: Receive buffer over flow!\r\n";这个有问题,不要操作UI控件,接收事件不在主线程中,没有同步非UI线程操作UI控件会出错的。
最简单的使用方法是使用一个Timer 定期检查串口有没有数据,如果有的话就读出来处理。
--------------------编程问答-------------------- 为啥非要1个字节就触发事件呢?线程读取 串口中有多少读多少,直到读不到,然后开始处理数据。
private void timer1_Tick(object sender, EventArgs e)
{
if (serialPort1.BytesToRead > 0)
{
byte[] buffer = new byte[serialPort1.BytesToRead];
serialPort1.Read(buffer, 0, buffer.Length);
// 处理........
}
}
如果使用线程调用界面刷新,需要Invoke方法。
个人认为,你不用设置1字节 触发接收事件 就OK的。
补充:.NET技术 , C#