private List<byte> RevBuffer = new List<byte>();private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
lock (RevBuffer)
{
var buffer = new byte[4000];
var len = 0;
while ((len = serialPort1.Read(buffer, 0, buffer.Length)) > 0)
RevBuffer.AddRange(buffer.Take(len));
ThreadPool.QueueUserWorkItem(h => //不等ProcessCommand执行完,立即重新读取串口新数据
{
while (ProcessCommand()) ; //处理收到的所有消息,直到再没有任务
});
}
}private bool ProcessCommand()
{
lock (RevBuffer)
{
var len = 查找一个命令的长度(RevBuffer);
if (len == 0) //不包含任何完整的任务(比如说还没有接受到第一个消息的结束标志
return false; var command = new byte[len];
Array.Copy( RevBuffer.ToArray() , command, len );
RevBuffer.RemoveRange(0, len ); //从接收缓冲区移除第一个消息内容
ThreadPool.QueueUserWorkItem(h => 执行一条命令(command));
return true; //通知调用程序,收到了一个任务
}
}
{
lock (RevBuffer)
{
var buffer = new byte[4000];
var len = 0;
while ((len = serialPort1.Read(buffer, 0, buffer.Length)) > 0)
RevBuffer.AddRange(buffer.Take(len));
ThreadPool.QueueUserWorkItem(h => //不等ProcessCommand执行完,立即重新读取串口新数据
{
while (ProcessCommand()) ; //处理收到的所有消息,直到再没有任务
});
}
}private bool ProcessCommand()
{
lock (RevBuffer)
{
var len = 查找一个命令的长度(RevBuffer);
if (len == 0) //不包含任何完整的任务(比如说还没有接受到第一个消息的结束标志
return false; var command = new byte[len];
Array.Copy( RevBuffer.ToArray() , command, len );
RevBuffer.RemoveRange(0, len ); //从接收缓冲区移除第一个消息内容
ThreadPool.QueueUserWorkItem(h => 执行一条命令(command));
return true; //通知调用程序,收到了一个任务
}
}
所有的线程都可以不开。实际的系统是为了性能和用户(UI交互时)操作体验而设计的。如果你只是完成基本逻辑,永远也不用考虑使用线程的。所以说,如果你在“还看不懂基本逻辑”的时候,你只要把 ThreadPool.QueueUserWorkItem(...) 这句话外边的“壳儿”去掉、仅留下里边的代码,就行了。
1、对于第一个问题:
首先定义全局变量List <byte> list =new List<byte>() //必须定义为全局
int b=0
然后在private void comm_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int a=comm.ByteToRead;
byte []buf=new byte[a];
comm.Read(buf,0,a);
for(i=0;i<a;i++)//用来将buf的数据拼接到list数组,以保证把完整的一帧数据加到一个数组里面
{
list.Insert(b,buf[i]);
b++;
}
if(list[list.account-1]==0xD0&&list[list.account-2]==0xDE)//判断数据是否收完;DE和D0为帧结束符在下面处理数据
{
对于第2个问题,利用LIST.Removerange(int ,length)//在指定索引处删除一定的长度
if(list[2]==0x08)
{
做相应处理;
list.removerange(0,6); }
if(list[2]==0x55)
{
做相应处理;
list.removerange(0,6); }
if(list[2]==0x66)
{
做相应处理;
}
list.Clear();//清空list用来下次接收
b=0;
}
}
详细的根据自己的通信协议按这个框架应该是可以的。
分享下,csdn就是分享知识的社区,yeah!
另外将来让程序变成一个教正规、可为中型应用而扩展的“设计升级”的建议:1. DataReceive中的程序,应该清晰地是处理这个Receive流程的。你应该把判断任务类型和调用处理程序的代码,从这段程序中分离出去,不应该在这里出现一堆的 if...else 判断。
2. 将来还是要在子线程中执行命令解析和调用处理程序过程,而 Receive程序应该仅仅在从list中去掉一条条命令之后,立刻返回(不等命令执行就返回)。以免造成通讯延迟、甚至程序死锁。
另外,ifelse这个处理速度应该很快吧。你指的意思是在Receive程序里面开启一个线程吗,在这个线程里用来处理数据吗。