从网上搜索,解决这个问题有两个方式:

  解决办法有两种,
  一个是在DataReceived事件里加入
  System.Threading.Thread.Sleep(600); 
  byte[] buffer=new byte[commPlc.BytesToRead];
  这样可以等待缓冲区的数据缓冲好,一次接收数据,也就是只触发一次DataReceived事件

  方法二:
  将instr定义成全局变量,删除事件里的instr="";这样可以保证每次触发的时候不会清空instr

 

方法一的缺点是代码量大,而且是明明可以等待若干毫秒后,接收缓存区会自动填满。这这时再去取值。就无需自动建立“缓存区”。这个方法属于重复建立缓存区。

方法二的缺点也很明显。由于数据量不同,固定等待时间天然存在bug和浪费时间。

笔者尝试了一种新的方式,克服上面两种方式的缺点。

 

 这样,不管数据多长,最多浪费20ms

而且从缓冲区取到的数值就是自己需要的数值。

测试结果如下:

  

 

 

 

 整个测试下来,读取25个bytes,有些时候只需要等待1次,大多数情况等待2次或3次。即测试成功!