C# serial port之WriteTimeout和ReadTimeout问题

LaiLai_Fido 2018-12-25 11:27:22
最近在使用串口读取数据,由于要使用两个串口来读取数据,当然数据返回肯定有先后,或者一个串口返回了完整的数据,一个串口返回了部分数据。这样我需要设置ReadTimeout时间,但是一直没有用,即使我设置ReadTimeout=1, 即1毫秒也没用(实际数据要等待2秒多才开始返回,共一次返回36个ASCII字符)。
我想问,这个ReadTimeout时间具体是从什么时候开始计算的?
1. 是从DataReceived事件触发开始计算?即触发了接收数据之后开始计算Timeout时间?我设置的波特率=9600,也就是每秒发送9600字符,得知每个字符需要(1/9600)秒,大于我所设置的ReadTimeout=1的时间,那就算超时了,会按照超时执行到catch里面,但是实际没有这么做,程序一直在等待过程中。
2. 是从串口发送数据开始计算?那中间需要等待2秒多,肯定也算超时了。

所以不知道该怎么理解这个ReadTimeout时间,CSDN里一直没有查到我想要的答案,请各位高手能否详细解释下。谢谢!
private void S1Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int count=0;
if (S1Com.IsOpen)
{
try
{
Listening = true;
int n = S1Com.BytesToRead;
Byte[] receivedData = new byte[n]; //创建接收字节数组
S1Com.Read(receivedData, 0, n); //读取数据
//S1Com.DiscardInBuffer();
buffer1.AddRange(receivedData);

if (buffer1.Count == 36)
{

buffer1.CopyTo(0, HexData_1, 0, 36);

string strResult1 = Encoding.ASCII.GetString(HexData_1);

this.txtBoxS1.Invoke((EventHandler)(
delegate
{
this.txtBoxS1.Text = Encoding.ASCII.GetString(HexData_1);
}));

TestResult1(strResult1);
}

}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "出错提示");
txtBoxS1.Text = "";
}
finally
{
Listening = false;
}
}
}

...全文
4459 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
海底石鱼 2020-11-27
  • 打赏
  • 举报
回复 7
引用 9 楼 以专业开发人员为伍 的回复:
那你使用的是 windows 操作系统吧?!windows桌面操作系统是为了桌面图形操作而设计的,同一时间往往有上千线程,做不到每1毫秒就调用一次你的进程。 如果非要纠结比较低级的工业控制思路,不要用高级的windows操作系统,你使用“裸机”然后使用汇编语言或者纯 c 语言来编写你自己的操作系统和应用系统,你自己跟 BIOS 打交道,你自己控制端口读写和中断等。 满脑子只有底层工控操作的,并不适合在高级的 windows 开发。
你在这牛逼你妈呢?
龙宜坡 2018-12-27
  • 打赏
  • 举报
回复
@sp1234 多年没来“床上等你”,P哥依然很活跃。 刚入行时就搞的上位机用串口控制下位机,恰好,一上床就遇见这个问题。 题主这个问题,我开始搞时比你还懵逼。 首先,你的电脑CPU运算速度相比下位机CPU,那可是相当相当快。 比如,一个成年人(上位机)问一个4岁小孩(下位机),“7+2等于几呀?",小孩才掰指头算,需要一个等待答复的时间。 上位机发出了消息,需要一个等待时间,等待下位机运算完成后才回答。 波特率可以理解为小孩说话的速度,而这个等待时间(timeout)可以理解为你最大等待小孩多久算出来。 两秒不算多,而且这两秒什么也不干,就等下位机给回答。 以上,可以这样理解吗?
  • 打赏
  • 举报
回复
那你使用的是 windows 操作系统吧?!windows桌面操作系统是为了桌面图形操作而设计的,同一时间往往有上千线程,做不到每1毫秒就调用一次你的进程。 如果非要纠结比较低级的工业控制思路,不要用高级的windows操作系统,你使用“裸机”然后使用汇编语言或者纯 c 语言来编写你自己的操作系统和应用系统,你自己跟 BIOS 打交道,你自己控制端口读写和中断等。 满脑子只有底层工控操作的,并不适合在高级的 windows 开发。
平底锅锅锅 2018-12-27
  • 打赏
  • 举报
回复
引用 4 楼 LaiLai_Fido 的回复:
[quote=引用 1 楼 C_gyl 的回复:]
读取操作(未完成时发生)超时之前的毫秒数。也就是对正常读取,这个参数没作用。它是让你在读取出问题时,等待这个超时后,还能返回。你试试不设置Read超时,如果不用try,可能会卡在那里。

什么叫做“读取出问题”?是不是可以这么认为:因为只是读取数据,即使有问题也只是读不到数据?
我可不可以做个这样的实验:打开一个串口,但是串口另外一端不接任何设备,那么我发送一个数据过去,肯定不会收到任何返回,这样就存在“读取操作超时”还是会被认为“发送超时”?[/quote]
你和另一个串口通信,故意不让另一个串口给你返回,Read会超时,你设置的超时会起作用。Write一般可能是自身串口有问题或者子这个串口连接的控制出问题,会超时,也就是设置的写超时会起作用。
xuzuning 2018-12-27
  • 打赏
  • 举报
回复
对的,是超时了
串口驱动是在读缓冲区满了和出现异常(比如超时)的时候,发出本轮读操作结束的通知的
按照你的设置,应该是你的 S1Com.Read 每次只读到一个字节
LaiLai_Fido 2018-12-26
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
从开始读算起 另外你对 波特率=9600 的理解有误 波特率 值的是每秒二进制位的个数,一个字节8个二进制位,加一个起始位,一个结束位。也就是每10个二进制位表示一个字节 9600 表示每秒960字节传输量 SerialPort 是按字节处理传输数据的,不要搞混淆了
谢谢你的解释。按照你的说明,每个字节需要(1/960=0.00104)秒时间,也就是大于1毫秒。也就是说两个字节之间至少需要1毫秒多点的时间,那我设置ReadTimeout=1(就是1毫秒),从读取第一个字节到第二个字节应该超过1毫秒,算超时了呀。 不知道我的理解对不对?
LaiLai_Fido 2018-12-26
  • 打赏
  • 举报
回复
引用 3 楼 wf2397108372 的回复:
这个读取超时指的是
S1Com.Read(receivedData, 0, n);
这个方法的超时时间,也就是说如果这个方法可以一直读取到数据就不存在超时的问题。
可是我这边存在收取不到数据的情况,也就是我用read方法读不到缓存里的数据,然后就一直等在那里,没有因为超时而走到catch里面
LaiLai_Fido 2018-12-26
  • 打赏
  • 举报
回复
引用 1 楼 C_gyl 的回复:
读取操作(未完成时发生)超时之前的毫秒数。也就是对正常读取,这个参数没作用。它是让你在读取出问题时,等待这个超时后,还能返回。你试试不设置Read超时,如果不用try,可能会卡在那里。
什么叫做“读取出问题”?是不是可以这么认为:因为只是读取数据,即使有问题也只是读不到数据? 我可不可以做个这样的实验:打开一个串口,但是串口另外一端不接任何设备,那么我发送一个数据过去,肯定不会收到任何返回,这样就存在“读取操作超时”还是会被认为“发送超时”?
  • 打赏
  • 举报
回复
这个读取超时指的是
S1Com.Read(receivedData, 0, n);
这个方法的超时时间,也就是说如果这个方法可以一直读取到数据就不存在超时的问题。
xuzuning 2018-12-26
  • 打赏
  • 举报
回复
从开始读算起

另外你对 波特率=9600 的理解有误
波特率 值的是每秒二进制位的个数,一个字节8个二进制位,加一个起始位,一个结束位。也就是每10个二进制位表示一个字节
9600 表示每秒960字节传输量
SerialPort 是按字节处理传输数据的,不要搞混淆了
平底锅锅锅 2018-12-26
  • 打赏
  • 举报
回复
读取操作(未完成时发生)超时之前的毫秒数。也就是对正常读取,这个参数没作用。它是让你在读取出问题时,等待这个超时后,还能返回。你试试不设置Read超时,如果不用try,可能会卡在那里。

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧