C#串口问题:接收事件触发的问题

123YYD 2018-01-06 05:09:03
最近做了个循环向串口发送数据的例子,要求获取返回值,并显示在同一txtBox中。功能是实现了,但是显示结果是却是所有发送数据显示完才显示接收数据,我想要的结果是发一条数据显示一条返回结果,有没有做过这类功能的大神提示一下。
代码附上:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace LoopPort_send_received
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

SerialPort serp =new SerialPort();


//定义事件处理函数
private void serialport_DataReceived(Object sender, SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep(100); //(毫秒)等待一定时间,确保数据的完整性 int len
int len = serp.BytesToRead;
if (len != 0)
{
byte[] buff = new byte[len];
serp.Read(buff, 0, len);
//try some other functions to read? do yourself if intersted
//processing data in buff
this.textBox1.BeginInvoke(
new MethodInvoker(()=>
{
this.textBox1.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+" "+ buff[0]+"\r\n");
}));
}
}
catch(Exception)
{

}
}

private void Form2_Load(object sender, EventArgs e)
{
//设置接收超时。一旦超时,将抛出Exception
serp.ReadTimeout = 90 * 1000;
serp = new SerialPort("COM7", 9600, Parity.Even, 7, StopBits.One);
//注册事件处理函数
serp.DataReceived += new SerialDataReceivedEventHandler(serialport_DataReceived);
}

private void button1_Click(object sender, EventArgs e)
{
List<byte[]> list = new List<byte[]>();
list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x34, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x35 });
list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x38, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x39 });
for (int i = 0; i < 2; i++)
{
if (serp.IsOpen)
serp.Close();
serp.Open();
serp.Write(list[i], 0, 15);
this.textBox1.Text +=string.Format("第{0}个",i+1) + "\r\n";
Thread.Sleep(5000);
}

}
}
}
...全文
1001 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
123YYD 2018-01-06
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
定时器不要乱写 for 循环语句。定时器就是要定时执行,你写成循环岂不是“死”了吗?循环语句就是坑。 定时器类似于这样使用
private void button1_Click(object sender, EventArgs e)
{
    list.Clear();
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x34, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x35 });
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x38, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x39 });
    i = 0;
    timer1.Start();
}

timer1_Elapsed(object sender, ElapsedEventArgs e)
{
    serp.Open();
    serp.Write(list[i], 0, 15);
    serp.Close();
    this.textBox1.Text += string.Format("第{0}个", i + 1) + "\r\n";
    if (i == 2)
        timer1.Stop();
    else 
        i++;
}
根本没有什么循环 for、while 语句。只要看到循环语句,你就知道这根本不是定时执行、异步执行代码的编程思路。
太感谢您了,我解决问题了,太棒了!!!!!!!!!!!!!!!!!!!!!!
123YYD 2018-01-06
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
定时器不要乱写 for 循环语句。定时器就是要定时执行,你写成循环岂不是“死”了吗?循环语句就是坑。 定时器类似于这样使用
private void button1_Click(object sender, EventArgs e)
{
    list.Clear();
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x34, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x35 });
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x38, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x39 });
    i = 0;
    timer1.Start();
}

timer1_Elapsed(object sender, ElapsedEventArgs e)
{
    serp.Open();
    serp.Write(list[i], 0, 15);
    serp.Close();
    this.textBox1.Text += string.Format("第{0}个", i + 1) + "\r\n";
    if (i == 2)
        timer1.Stop();
    else 
        i++;
}
根本没有什么循环 for、while 语句。只要看到循环语句,你就知道这根本不是定时执行、异步执行代码的编程思路。
也就是说我就是加个定时器,来控制循环
  • 打赏
  • 举报
回复
if (i == 2)
可能要改为
if (i == 1)
根据你的实际来设置。 总之,要杜绝把交互式程序流程理解成“循环、顺序”的那种函数式流程。既然是交互的、定时的、异步的,就绝对不可能只执行个什么循环语句来异步(即使是c# 6 的 await/async 语法,也是要首先理解异步回调概念,它也只是假顺序,也不是顺序执行的)。
  • 打赏
  • 举报
回复
定时器不要乱写 for 循环语句。定时器就是要定时执行,你写成循环岂不是“死”了吗?循环语句就是坑。 定时器类似于这样使用
private void button1_Click(object sender, EventArgs e)
{
    list.Clear();
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x34, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x35 });
    list.Add(new byte[] { 0x02, 0x31, 0x31, 0x34, 0x30, 0x38, 0x30, 0x32, 0x31, 0x45, 0x30, 0x30, 0x03, 0x33, 0x39 });
    i = 0;
    timer1.Start();
}

timer1_Elapsed(object sender, ElapsedEventArgs e)
{
    serp.Open();
    serp.Write(list[i], 0, 15);
    serp.Close();
    this.textBox1.Text += string.Format("第{0}个", i + 1) + "\r\n";
    if (i == 2)
        timer1.Stop();
    else 
        i++;
}
根本没有什么循环 for、while 语句。只要看到循环语句,你就知道这根本不是定时执行、异步执行代码的编程思路。

110,539

社区成员

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

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

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