官方提醒4 2023-03-20 19:26 采纳率: 68.2%
浏览 63

C#不会自己运行清理缓存数据

目前有一段代码 buffer[5] ==0x02不成立的时候 我加上弹窗以后。只要弹出来窗口 我点一下确定 就可以继续运行程序,如果我不加弹窗 buffer[5] ==0x02不成立的时候 就卡住了 就不在接收串口数据了 不会自己运行 buffer.Clear();


        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            
            CheckForIllegalCrossThreadCalls = false;                                                        // 检查是否允许跨线程调用控件,这里为了简化代码直接禁用了该功能

            int bytesToRead = serialPort1.BytesToRead;                                                     // 读取所有可用字节数

            byte[] receiveBuffer = new byte[bytesToRead];                                              //用于存储接收到的数据

            serialPort1.Read(receiveBuffer, 0, bytesToRead);                                          //从串口读取数据

            buffer.AddRange(receiveBuffer);                                                                  //写入缓存中
            if (buffer.Count > 0 &&  buffer[0] == 0x68)                                                 //判断缓存中的数据
            {
                
                if(buffer.Count>=10)                                          //判断缓存中的数据
                {
                    if (buffer[5] ==0x02)
                    {
                        byte[] data = buffer.GetRange(0, 10).ToArray();                                   // 讲缓存中的数据存入列表内
                        receivedString = BitConverter.ToString(data).Replace("-", "");             // 转换为字符串
                        textBox1.AppendText(receivedString);                                                 //输出到textBox
                        string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");         // 时间 
                        StreamWriter sw = new StreamWriter(@"C:\Users\guoxiaoru\Desktop\ACVB.txt", true);         //写入文件夹
                        sw.WriteLine(timeStr + "   " + receivedString, "\n");
                        sw.Close();
                        buffer.RemoveRange(0, 10);
                    }
                    else {
                        MessageBox.Show("此时buffer[5] ==0x02不成立");
                        buffer.Clear(); 
                    }
                }
            }
            else { buffer.Clear(); }
        }

       private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            
            CheckForIllegalCrossThreadCalls = false;                                                        // 检查是否允许跨线程调用控件,这里为了简化代码直接禁用了该功能

            int bytesToRead = serialPort1.BytesToRead;                                                     // 读取所有可用字节数

            byte[] receiveBuffer = new byte[bytesToRead];                                              //用于存储接收到的数据

            serialPort1.Read(receiveBuffer, 0, bytesToRead);                                          //从串口读取数据

            buffer.AddRange(receiveBuffer);                                                                  //写入缓存中
            if (buffer.Count > 0 &&  buffer[0] == 0x68)                                                 //判断缓存中的数据
            {
                
                if(buffer.Count>=10)                                          //判断缓存中的数据
                {
                    if (buffer[5] ==0x02)
                    {
                        byte[] data = buffer.GetRange(0, 10).ToArray();                                   // 讲缓存中的数据存入列表内
                        receivedString = BitConverter.ToString(data).Replace("-", "");             // 转换为字符串
                        textBox1.AppendText(receivedString);                                                 //输出到textBox
                        string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");         // 时间 
                        StreamWriter sw = new StreamWriter(@"C:\Users\guoxiaoru\Desktop\ACVB.txt", true);         //写入文件夹
                        sw.WriteLine(timeStr + "   " + receivedString, "\n");
                        sw.Close();
                        buffer.RemoveRange(0, 10);
                    }
                    else {
                        //MessageBox.Show("此时buffer[5] ==0x02不成立");
                        buffer.Clear(); 
                    }
                }
            }
            else { buffer.Clear(); }
        }
  • 写回答

2条回答 默认 最新

  • wanghui0380 2023-03-20 20:42
    关注

    哎,如果不从基础概念出发,可以说你再发一个月50个帖子,你也无法完成

    已经回复过了,如果你想真正解决,你必须明白串口,网口这类流数据完全不是你认为那个模样的

    虽然博文无数,但是目前来说最正确的途径是system.io.pipelines。因为这个是官方的“环形内存”,兼顾NIO内存复用,环形字节池,背压控制,并行读写多种功能

    在回来看你的代码,我前面回复过我故意在前面的帖子里回复,在0x68前面特地加个0x00,其实就是提示你串口接受的的数据大概率并非你认为的buffer[0]=0x68,也大概率不是你认为的,buffer.count>10

    你现在搞个list,算是刚沾个边。但是使用方式又完全不沾边。
    首先来说你为啥弄个list,我想你应该发现了,数据不是每次都刚刚好一包,也许半包,也许1包,也许2包,也许1.5包,所以你用list存。

    那么请问如果收到1.5包,而且是你认为好数据,你clear了,然后接着收那么buffer0是不是不一定是0x68

    所以正常方案其实前面很多人已经说了,其实是用个buffer存起来,然后查找第一个0x68的index,然后从这个index在查找是否符合要求,如果符合就移除第一个符合的包(不是clear,而是移除),接着继续循环直到找不到任何一个符合的,因为是stream流,他无始无终,我们只是找到其中一段符合的,同时移除此段之前的。保留此段之后的已备和下次的数据拼接了一起判定

    这个过程buffer会不断分配内存调整内存,玩的好就行,玩不好就挂

    所以官方为了照顾大众,特地给你提供system.Io.pipelines这种东西来搞

    你要始终避开这种东西,总靠某个园子不靠谱的博文干活,前面坑多啊,996都不够填

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月20日

悬赏问题

  • ¥15 工价表引用工艺路线,应如何制作py和xml文件
  • ¥15 根据历史数据,推荐问题类型
  • ¥15 需要仿真图,简单的二阶系统实例
  • ¥15 stm32光控照明仿真
  • ¥15 使用人工智能的方法生成满足一定统计参数要求的随机数序列
  • ¥15 SENT协议中相关问题咨询
  • ¥15 URL地址href跳转问题
  • ¥15 mysql数据库备份恢复
  • ¥15 mmdetection mask-rcnn
  • ¥25 matlab可以将微分方程的解显示为相图形式吗