c# 串口通信 DataReceived 事件触发方法的使用

DataReceived事件:在接收到了ReceivedBytesThreshold设置的字符个数或接收到了文件结束字符并将其放入了输入缓冲区时被触发。数据接收的方法如果采用轮询的方法比较浪费时间,采用DataReceived事件触发的方法,合理的设置ReceivedBytesThreshold的值,若接收的是定长的数据,则将ReceivedBytesThreshold设为接收数据的长度,若接收数据的结尾是是固定的字符或字符串则可采用ReadTo的方法或在DataReceived事件中判断接收的字符是否满足条件。SerialPort读取数据的许多方法都是同步阻塞调用,尽量避免在主线程中调用,可以使用异步处理或线程间处理调用这些读取数据的方法。
Hcom.DataReceived += new SerialDataReceivedEventHandler(H_Decode_com_DataReceived);
Hcom.ReceivedBytesThreshold = 13;
 

开始时我用while阻塞的方式来保证每次触发DataReceived时把数据取完整:

void H_Decode_com_DataReceived(object sendr, SerialDataReceivedEventArgs e)
{
    byte[] Resoursedata = new byte[6];
    while (Hcom.BytesToRead < 6)
    {
        Thread.Sleep(1);
    }
 
    if (Hcom.BytesToRead >= 6)
    {
         Hcom.Read(Resoursedata, 0, 6);
         if (Resoursedata[3] == (byte)0x01)
    {
         while (Hcom.BytesToRead < 7)
         {
             Thread.Sleep(5);
         }
         if (Hcom.BytesToRead >= 7)
         {
             byte[] HReadbuffer = new byte[7];
             Hcom.Read(HReadbuffer, 0, 7);
             DeviceHandler._HPcmToAmbeBufferQueue.SendMsg(HReadbuffer);
         }
    }
    else if (Resoursedata[3] == (byte)0x02)
    {
 
         while (Hcom.BytesToRead < 320)
         {
              Thread.Sleep(5);
         }
 
              byte[] HReadbuffer = new byte[320];
              Hcom.Read(HReadbuffer, 0, 320);
              DeviceHandler._HAmbeToPcmBufferQueue.SendMsg(HReadbuffer);
    }
    else
    {
        Log.Error("BytesToRead error");
        Hcom.DiscardInBuffer();
    }
}

但测试时发现这种方式在遇到串口数据过大时会导致CPU占用率过高

之后更改为:

void H_Decode_com_DataReceived(object sendr, SerialDataReceivedEventArgs e)
        {
            int readByte = Hcom.BytesToRead;
            byte[] Resoursedata = new byte[13];
            if (readByte >= 13)
            {
                if (step == 0)
                {
                    Hcom.Read(Resoursedata, 0, 6);
                    if (Resoursedata[3] == (byte)0x01)
                    {
                        byte[] HReadbuffer = new byte[7];
                        Hcom.Read(WTReadbuffer, 0, 7);
                        DeviceHandler._HPcmToAmbeBufferQueue.SendMsg(HReadbuffer);
                    }
                    else if (Resoursedata[3] == (byte)0x02)
                    {
                        step++;
                    }
                }
                else if (step > 0)
                {
                    if (readByte >= 320)
                    {
                        byte[] HReadbuffer = new byte[320];
                        Hcom.Read(HReadbuffer, 0, 320);
                        DeviceHandler._HAmbeToPcmBufferQueue.SendMsg(HReadbuffer);
                        step = 0;
                    }
                }
            }
        }

因为C# serialport 提供的DataReceived,当触发了事件后就会调用事件函数,不论之前那个有没有处理完,所以每次调用事件函数时一定要保证快速的执行完,防止下次的触发事件在上一次还没执行完就又开始了。所以最后改为每次只检查串口接收缓冲区中存储的数据量,不在那里等待,直到满足数量要求后再取出来。


————————————————
 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值