C# ISP 串口调试工具的开发(二)—— 多线程处理

C# ISP 串口调试工具的开发(二)—— 多线程处理

前言

上一篇文章《ISP 串口调试工具的开发(一)》介绍了如何实现一个简单具有读写功能的串口调试工具,这篇文章会介绍进阶版的串口调试工具。

因为上一篇文章的所有读写操作都是在主线程中进行的,但是这样存在一个弊端,因为在 Windows 的桌面开发中,由于界面编程中的 “Windows 消息队列” 机制,当在主线程(UI 线程)中有耗时较长的操作的话,就会造成界面卡、不流畅、反应慢等现象。如果界面出现长时间静止,会造成使用者觉得软件卡死的错觉。可以查看《.net开发笔记(十三)Winform 常用开发模式第一篇》了解更多。

数据接收

在接收数据时,可以使用 SerialPort.DataRecevied 事件来接收,也可以为数据接收新开启一个新线程。

使用事件接收

使用 SerialPort.DataRecevied 事件接收数据,需要注册接收事件创建 SerialDataReceivedEventHandler 委托,即把接收数据的事件关联到相应的事件去,否则接收事件发生时无法触发对应的方法, DataRecevied 只做数据接收,数据处理则是交给了委托进行。

private void Demo_Load(object sender, EventArgs e)
{
   
   
	Init_Port_Confs();
	serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
}

private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   
   
	if(serialPort.IsOpen)
	{
   
   
		byte[] receviedData = new byte[serialPort.BytesToRead];
		serialPort.Read(receviedData, 0, receivedData.Length);
		//数据处理操作
	}
}

使用线程接收

本文采用的是开启新的监听线程方式,当点击读取参数的按钮后,开启一个新线程 loadThread 关联委托方法 LoadData,将数据的处理放在委托中:

/// <summary>
/// 读取参数按钮事件
/// </summary>
private void BtnGetData_Click(object sender, EventArgs e)
{
   
   
    if (!serialPort.IsOpen)
    {
   
   
        MessageBox.Show("串口未连接!", "传输错误");
        return;
    }

    BtnSendParams.Enabled = false;
    BtnGetParams.Enabled = false;

    Thread loadThread = new Thread(LoadData);
    try
    {
   
   
        loadThread.Start();
    }
    catch (Exception exception)
    {
   
   
        MessageBox.Show(exception.Message);
        loadThread.Abort();
    }
}

LoadData 中,读取了缓冲区中的数据后将参数渲染到对应的 TextBox

/// <summary>
/// 加载参数
/// </summary>
private void LoadData()
{
   
   
    // 清空缓冲区
    serialPort.DiscardInBuffer();

    int byteCount = 0;
    while (byteCount < 3)
    {
   
   
        byteCount = serialPort.BytesToRead;
    }

    // 获取数据并检查响应数据
    byte[] data = new byte[byteCount];
    serialPort.Read(data, 0, byteCount);

    //展示数据
    int index, value;
    string controlName;
    // 循环读取参数
    for (int i = 0; i < data.Length; i += 3)
    {
   
   
        index = (int)data[i];
        // 获取参数名
        controlName = "param" + index;
        // 获取参数值
        value = data[i + 1] * 256 + data[i + 2];

        TextBox textbox = (TextBox)Controls.Find(controlName, true)[0];
        textbox.Text = value.ToString();
    }

    CourseRecord("读取参数完成!");
    BtnSendParams.Enabled = true;
    BtnGetParams.Enabled = true;
}

数据发送

同样的,在数据发送中,也是开启一个新线程 sendThread 关联委托方法 SendData,数据处理交给委托方法:

/// <summary>
/// 发送参数按钮事件
/// </summary>
private void BtnSendParams_Click(object sender, EventArgs e)
{
   
   
    if (!serialPort.IsOpen)
    {
   
   
        MessageBox.Show("串口未连接!", "传输错误");
        return;
    }

    BtnSendParams.Enabled = false;
    BtnGetParams.Enabled = false;

    Thread sendThread = new Thread(SendData);
    try
    {
   
   
        sendThread.Start();
    }
    catch (Exception exception)
    {
   
   
        MessageBox.Show(exception.Message);
        sendThread.Abort();
    }
}

SendData 中,先清空发送缓冲区的数据,然后读取非空的参数发送出去:

/// <summary>
/// 发送数据
/// </summary>
private void SendData()
{
   
   
    // 清空缓冲区
    serialPort.DiscardOutBuffer();

    ushort length = 0;

    // 计算参数个数
    foreach (Control control in groupParams.Controls)
    {
   
   
        if (control is TextBox && control.Text.Length != 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值