问题描述
其中第一行和第二行的数据是正确的。从图中的下划线部分应该在圈出来的那些0的位置这是给两个串口设备分别创建线程因为要定时接收数据,所以使用了timer来定时触发以下是上图中publicclassGetData{publicSerialPortCom;stringdeviceType;stringcomPort="";intbaudRate=0;stringcode="";RichTextBoxRTB;publicGetData(stringcomPort,intbaudRate,stringcode,RichTextBoxRTB,stringdeviceType){this.comPort=comPort;this.baudRate=baudRate;this.code=code;this.deviceType=deviceType;this.RTB=RTB;if(deviceType=="01"){Com=newSerialPort(comPort);Com.BaudRate=baudRate;Com.DataReceived+=newSerialDataReceivedEventHandler(Com_WaterDataReceived);Com.ReceivedBytesThreshold=16;Com.Open();//发送代码string[]cmd=("FB53FF0001010000000000000000FB54").Split('');List<byte>bytes=newList<byte>();for(inti=0;i<cmd.Length;i++){bytea=Convert.ToByte(cmd[i],16);bytes.Add(a);}byte[]buffer=bytes.ToArray();Com.Write(buffer,0,buffer.Count());}elseif(deviceType=="02"){Com=newSerialPort(comPort);//Com.BaudRate=baudRate;Com.DataReceived+=newSerialDataReceivedEventHandler(Com_leakageReceived);Com.ReceivedBytesThreshold=5;Com.Open();}}privatevoidCom_WaterDataReceived(objectsender,SerialDataReceivedEventArgse){System.IO.Ports.SerialPortcom=(System.IO.Ports.SerialPort)sender;byte[]buffer=newbyte[16];com.Read(buffer,0,16);stringss;ss=byteToHexStr(buffer);//用到函数byteToHexStrRTB.Text+="【微水】【"+DateTime.Now.ToString()+"】:"+ss+"n";cancelEvent("01");}privatevoidCom_leakageReceived(objectsender,SerialDataReceivedEventArgse){System.IO.Ports.SerialPortcom=(System.IO.Ports.SerialPort)sender;RTB.Text+="【泄露】【"+DateTime.Now.ToString()+"】:"+com.ReadExisting().ToString()+"n";com.DiscardInBuffer();com.DiscardOutBuffer();cancelEvent("02");}privatevoidcancelEvent(stringdeviceType){if(deviceType=="01"){Com.DataReceived-=newSerialDataReceivedEventHandler(Com_WaterDataReceived);}elseif(deviceType=="02"){Com.DataReceived-=newSerialDataReceivedEventHandler(Com_leakageReceived);}}publicvoidaddEvent(stringdeviceTpye){if(deviceTpye=="01"){Com.DataReceived+=newSerialDataReceivedEventHandler(Com_WaterDataReceived);string[]cmd=("FB53FF0001010000000000000000FB54").Split('');List<byte>bytes=newList<byte>();for(inti=0;i<cmd.Length;i++){bytea=Convert.ToByte(cmd[i],16);bytes.Add(a);}byte[]buffer=bytes.ToArray();Com.Write(buffer,0,buffer.Count());}elseif(deviceTpye=="02"){Com.DataReceived+=newSerialDataReceivedEventHandler(Com_leakageReceived);}}///<summary>///字节数组转16进制字符串///</summary>///<paramname="bytes"></param>///<returns></returns>publicstaticstringbyteToHexStr(byte[]bytes){stringreturnStr="";if(bytes!=null){for(inti=0;i<bytes.Length;i++){returnStr+=bytes[i].ToString("X2");}}returnreturnStr;}}}
那么问题来了1.最上面的图里面数据丢失位用0填充是因为多线程的关系还是什么?2.接收缓冲区的大小已经设置了,为什么有时会收到几倍设置的大小的数据?3.对多个串口设备的定时接收数据,像我这样为每个设备开个线程,再在线程里面用timer来接收数据的写法对吗?刚接触串口通信和线程,跪求大家指点指点
解决方案
解决方案二:
麻烦大家帮忙看一下吧
解决方案三:
用DataReceived+多线程就可以了。不用什么timer因为数据是一直发送的,再使用timer容易造成数据丢失。
解决方案四:
引用2楼SlowlyHeart的回复:
用DataReceived+多线程就可以了。不用什么timer因为数据是一直发送的,再使用timer容易造成数据丢失。
这样要定时的话是是直接用thread.sleep()吗?本来是这么写的,老师非叫用timer
解决方案五:
开个线程专门接收数据放到一个数据链表里,什么都不做!另起线程或timer,处理数据链表里的命令,这样不会出错!除非数据线有问题