搜索
bottom↓
回复: 13

C#入门问题?SerialPort控件DataReceived事件能否每个字节触发1次

[复制链接]

出130入129汤圆

发表于 2013-10-27 12:00:24 | 显示全部楼层 |阅读模式
本帖最后由 68336016 于 2013-10-27 13:19 编辑

一直用VC,看别人用C#也挺好的,于是看了下C#,做个串口程序,用SerialPort控件。

SerialPort控件属性中 receivedbytesthreshold为1,应该理解成内部缓冲区有1个字节就触发一次DataReceived事件?

实际中好像不是,如果我一次发送10个字节给SerialPort控件来接收,
在DataReceived事件处理函数中调用ReadByte()读取,并不会产生10次事件。
在事件处理函数中 查看serialPort1.BytesToRead,得到的结果是10。
也就是说DataReceived事件是不能保证一个字节产生一次事件?

出0入442汤圆

发表于 2013-10-27 12:23:57 | 显示全部楼层
PC有缓冲的。你可以把缓冲设置为1,但是这样做,丢字节的风险会大幅下降,因为PC不是实时的。

出130入129汤圆

 楼主| 发表于 2013-10-27 12:36:02 | 显示全部楼层
wye11083 发表于 2013-10-27 12:23
PC有缓冲的。你可以把缓冲设置为1,但是这样做,丢字节的风险会大幅下降,因为PC不是实时的。 ...

以前用VC时候习惯使用一个老外写的CSerialPort类,每收到1个字节就能产生1个事件。
第一次接触C#,才知道有不能完全保证的这种说法,不过搞清楚怎么回事也不影响使用,我在DataReceived事件函数中查询ByteToRead,再一次性读完。

出0入442汤圆

发表于 2013-10-27 12:42:16 | 显示全部楼层
68336016 发表于 2013-10-27 12:36
以前用VC时候习惯使用一个老外写的CSerialPort类,每收到1个字节就能产生1个事件。
第一次接触C#,才知道 ...

不是不影响使用,而是你得改变自己的观念。记住一点:现在的PC不适合处理单个数据,而是一次处理批量数据。当你速率足够高时,PC是处理不过来的。只有一次缓冲一批数据,再一次处理,PC才能搞得定。

出105入79汤圆

发表于 2013-10-27 12:56:18 | 显示全部楼层
当然可以,我做实时绘图就是这样的http://v.youku.com/v_show/id_XNjIwNTY4OTYw.html

出130入129汤圆

 楼主| 发表于 2013-10-27 13:06:12 | 显示全部楼层
qwe2231695 发表于 2013-10-27 12:56
当然可以,我做实时绘图就是这样的http://v.youku.com/v_show/id_XNjIwNTY4OTYw.html

你代码中是一个字节产生一个DataReceived事件?

这是微软说的:
http://msdn.microsoft.com/zh-cn/ ... t.datareceived.ASPX
DataReceived 和 ErrorReceived 事件,并且在基础流报告错误和执行事件处理程序之间会稍微延迟。 一次只能执行一个事件处理程序。
不保证对接收到的每个字节引发 DataReceived 事件。 使用 BytesToRead 属性确定缓冲区中剩余的要读取的数据量。

出0入0汤圆

发表于 2013-10-27 13:08:30 | 显示全部楼层
for循环一下不就是了么

出130入129汤圆

 楼主| 发表于 2013-10-27 13:17:01 | 显示全部楼层
zhujinliang2124 发表于 2013-10-27 13:08
for循环一下不就是了么

读取数据这当然简单,我只不过是想搞清楚DataReceived事件跟收到的字节的关系而已,不过看微软网站这么说,肯定是不可能1个字节1次事件的了。

出0入0汤圆

发表于 2013-10-27 13:32:11 | 显示全部楼层
68336016 发表于 2013-10-27 13:17
读取数据这当然简单,我只不过是想搞清楚DataReceived事件跟收到的字节的关系而已,不过看微软网站这么说 ...

哦,错怪了,呵呵

控件内部开了个线程隔一段时间就查看一下缓冲区,发现缓冲区内有了新的数据了,并且数据字节数大于ReceivedBytesThreshold,则触发事件

如果你发的慢点,间隔大于内部检查缓冲区的速度(貌似用异步不能控制这个速度),ReceivedBytesThreshold设置为1,就可以一字节一个事件了。当然这对于你的实际应用来说,是废话。

出105入79汤圆

发表于 2013-10-27 13:45:56 | 显示全部楼层
本帖最后由 qwe2231695 于 2013-10-27 13:47 编辑

对不起楼主,看错了,我的不是每个字节读取的。
我开的缓冲区是4096 Byte,我是满一个数据包(几个字节), receivedbytesthreshold为数据包(几个字节),就触发中断,然后取一个数据包出来。

出0入0汤圆

发表于 2013-10-27 13:51:55 | 显示全部楼层
上次写的串口程序也存在这个疑惑,楼主是否已经有答案了?

出130入129汤圆

 楼主| 发表于 2013-10-27 14:01:14 | 显示全部楼层
sgzzour 发表于 2013-10-27 13:51
上次写的串口程序也存在这个疑惑,楼主是否已经有答案了?

答案就是:不一定每个字节触发一次。
所以还是得进入DataReceived事件处理函数后,读取ByteToRead才知道真正收到几个字节数据。

出0入0汤圆

发表于 2013-10-27 17:03:51 | 显示全部楼层
过来学习~~~谢谢分享!

出0入0汤圆

发表于 2013-12-16 15:11:08 来自手机 | 显示全部楼层
楼主上位机接受汉字乱码吗?你是怎样解决的?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 02:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表