C#学习笔记之使用线程使用

C#学习笔记之使用线程使用

1.背景:

在按键按下的事件回调函数里面发送一条指令,要等待COM口接受数据回调函数完成数据接收后,再发其他指令,显然这是不现实的,经实验不能在按键按下的事件回调函数里面执行死等COM数据接收完成,需要快进快出;故而通过ChatCPT,知道了使用线程的方法来处理COM接收的数据;

2.线程处理接收数据的实例

如下代码是我们根据chatGPT的建议修改的代码:

2.1数据处理线程创建

 public partial class MainForm : Form, IView
    {


        private ManualResetEvent dataProcessedEvent = new ManualResetEvent(false);

        // 数据处理线程
        private Thread dataProcessingThread;
        private bool isRunning = true;

        public MainForm()
        {
            InitializeComponent();
            InitializeCOMCombox();
            // 启动数据处理线程
            dataProcessingThread = new Thread(DataProcessingLoop);
            dataProcessingThread.Start();

        }
         // 窗体关闭事件处理程序
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            // 停止数据处理线程
            isRunning = false;
            dataProcessedEvent.Set(); // 解除线程等待状态
            dataProcessingThread.Join();
            base.OnFormClosing(e);
        }
 }

2.2 COM数据缓存到ComRecBuffer

    public void ComReceiveDataEvent(Object sender, SerialPortEventArgs e)
    {
        if (this.InvokeRequired)
        {
            try
            {
                Invoke(new Action<Object, SerialPortEventArgs>(ComReceiveDataEvent), sender, e);
            }
            catch (System.Exception)
            {
                //disable form destroy exception
            }
            return;
        }

        // 检查帧头是否为0xAA 0xBB
        if ((e.receivedBytes[0] == 0xAA) && (e.receivedBytes[1] == 0xBB)) // 帧头
        {
            // 检查接收长度是否与预期长度匹配
            if (e.receivedBytes[2] == e.receivedBytes.Length) // 接收长度是否完整
            {
                // 计算接收到数据的CRC16校验值
                int iCRC_Value = GetCRC16_CCITT(e.receivedBytes, e.receivedBytes.Length - 2);
                // 从接收数据的最后两个字节提取CRC值
                int iTemp = e.receivedBytes[e.receivedBytes.Length - 2] << 8;
                iTemp |= e.receivedBytes[e.receivedBytes.Length - 1];
                // 将计算出的CRC与接收到的CRC进行比较
                if (iCRC_Value == iTemp) // CRC16校验
                {
                    // 如果CRC匹配,则将数据复制到最终缓冲区
                    Array.Copy(e.receivedBytes, 5, ComRecBuffer, 0, e.receivedBytes.Length - 7);
                    // 触发数据处理完成事件
                    dataProcessedEvent.Set();
                }
            }
        }
    }

2.3 线程里面处理数据和指令发送

        // 数据处理循环
        private void DataProcessingLoop()
        {
            byte Status = 0;
            while (isRunning)
            {
                dataProcessedEvent.WaitOne();
                UInt16 cmd = (UInt16)((ComRecBuffer[0] << 8) + ComRecBuffer[1]);
                switch (cmd)
                {
                    case 0x0070:
                        if (ComRecBuffer[2] == 0x55)//NAK
                        {
                            byte[] bSendBuf = { 0 };
                            if (Status == 0)
                            {
                                //First NAK
                                SendSerialData((byte)Command_t.ReadBlock, 0x70, 2, bSendBuf, controller);
                                Status = 1;

                            }
                            else if (Status == 1)
                            {
                                //second NAK
                                Status = 0;
                                SendSerialData((byte)Command_t.ReadBlock, 0xF0, 10, bSendBuf, controller);
                            }
                        }
                        break;
                    case 0x00F0:
                        MessageBox.Show("Flash Update Mode!");
                        Status = 0;
                        break;
                    default: break;

                }
                Array.Clear(ComRecBuffer, 0, ComRecBuffer.Length);
            }
        }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值