串口优化问题

睡神在睡觉 2009-11-19 04:37:00
        private void COM_Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte bt = (byte)COM_Port.ReadByte();
if (bt == 0x5c)
b = true;
if (b == true)
{
if (j >= 288)
{
b = false;
Thread trd = new Thread(new ThreadStart(this.Recve));
trd.IsBackground = true;
trd.Start();
}
else
{
Recv_Buff[j] = bt;
j++;
}
}
}


中断中这么写的,但是读288个字节居然用了7,8秒,肯定不正常,求教怎么优化?
...全文
170 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
睡神在睡觉 2009-11-20
  • 打赏
  • 举报
回复
To BuilderC:

谢了~~搞定了,刚开始没明白你的意思,确实如此,收够了再丢弃,要不有效数据都丢弃了,呵呵,结贴了~~
睡神在睡觉 2009-11-19
  • 打赏
  • 举报
回复
To BuilderC:

谢了,似乎可以,还没搞好,一会回家接着弄,以前搞的数据量小直接读完解的,现在得不一样了,搞的头大,回家研究下,
trentliu 2009-11-19
  • 打赏
  • 举报
回复
记住了兄弟, 串口编程本质是对串口缓冲区的操作。 read, write 都是面向缓冲区。 所谓的丢数据也跟缓冲区有关。 不是直接写端口。读端口
睡神在睡觉 2009-11-19
  • 打赏
  • 举报
回复
To BuilderC:

奥,你的意思是当下发指令后串口连续接收数据,填满缓冲区之后再去从缓冲区里解我需要的东西是把?不知道这么干行不行,我先试试,谢了~~~^_^
trentliu 2009-11-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sleep0110 的回复:]
To BuilderC:

硬中断里休眠线程?那串口不堵死了啊?依旧丢数据的。串口和网络通信不一样啊,下位机每秒都在不停的返成千上万的数据上来,
[/Quote]

串口怎么能堵死? thread.sleep(500); 这500 毫秒里,串口一直在接收数据并填充接收缓冲区。
只是延迟你接收处理, 跟阻塞谈不上关系。
假设你觉得500毫秒界面会卡。 这倒是有可能。 可以用 backgroundwork 里,control.invoke 刷新界面好了。

你根本犯不着一次处理一个字节。 我的思路是一次处理整个缓冲区的数据。
alwaysyan 2009-11-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sleep0110 的回复:]
引用 1 楼 alwaysyan 的回复:
把if (j >= 288)改成if (j.length >= 288),你试下



j是int型变量,是个计数器。。。要它的长度没用
[/Quote]


if (j >= 288)
{
b = false;
Thread trd = new Thread(new ThreadStart(this.Recve));
trd.IsBackground = true;
trd.Start();
}
else
{
Recv_Buff[j] = bt;
j++;
}

我发现问题到哪了,你那个线程只开始了,根本就没关闭,这样就算你关闭了窗口,但是在系统进程里它还是有个进程,有点类似死循环了...
睡神在睡觉 2009-11-19
  • 打赏
  • 举报
回复
To BuilderC:

硬中断里休眠线程?那串口不堵死了啊?依旧丢数据的。串口和网络通信不一样啊,下位机每秒都在不停的返成千上万的数据上来,
trentliu 2009-11-19
  • 打赏
  • 举报
回复

private void COM_Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{

thread.sleep(500); //从激活事件开始,等待缓冲区填充,可加大填充率,一般测试都可以填满缓冲区。 不加这个你确实读取的数量不确定。因为激活事件激活条件就不确定。

int nByteNum = serialPort1.BytesToRead;
byte[] arraybyte = new byte[nByteNum];
serialPort1.Read(arraybyte, 0, nByteNum); 、
}

表象其实不是丢数据,是因为事件激活时,缓冲区数据没有填写多少,比如server 发了5个,client 收了2个就激活了事件。 你就读到了2个。
thread.sleep() 可以逐渐加到到人家发多少,你收多少的地步。 不信你可以测试一下
睡神在睡觉 2009-11-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 alwaysyan 的回复:]
把if (j >= 288)改成if (j.length >= 288),你试下

[/Quote]

j是int型变量,是个计数器。。。要它的长度没用
睡神在睡觉 2009-11-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 builderc 的回复:]
何必一次读一个,缓冲区有多少就读多少白

int nByteNum = serialPort1.BytesToRead;
byte[] arraybyte = new byte[nByteNum];
serialPort1.Read(arraybyte, 0, nByteNum);


[/Quote]
因为下位机向上位机这返数据的时候长度不固定没办法这么写,这样写总是丢数据,一个字节一个字节的读虽然慢点,但是不丢数据,再指教下吧。
trentliu 2009-11-19
  • 打赏
  • 举报
回复

何必一次读一个,缓冲区有多少就读多少白

int nByteNum = serialPort1.BytesToRead;
byte[] arraybyte = new byte[nByteNum];
serialPort1.Read(arraybyte, 0, nByteNum);

alwaysyan 2009-11-19
  • 打赏
  • 举报
回复
把if (j >= 288)改成if (j.length >= 288),你试下

110,536

社区成员

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

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

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