过家家~ 2023-10-31 17:52 采纳率: 50%
浏览 9
已结题

C# 串口读取与rabbitmq回传数据冲突

刚接触rabbitmq和串口通信,遇到了个问题,希望有懂的大拿可以指点一二。
开发的程序需要通过串口通信读取实时数据,然后将获取的数据处理后上传至队列,在上传数据的过程中必须要关闭串口(serial.Close()),否则代码会卡在连接服务器的过程,之后就是报错,报错信息如下:
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.IO.IOException:
connection.start was never received, likely due to a network timeout

如果在上传的步骤之前将serial提前关闭就不会出现这个问题,有时候还会出现程序卡顿假死的情况(概率很小),虽然不知道是不是这个原因导致的,但只有在给队列上传消息的时候才会遇到这个情况。
下面是我的代码:

 private void Menu_Load(object sender, EventArgs e)
        {
            //称重读数
            serial.PortName = "COM16";
            serial.BaudRate = 9600;
            serial.DataBits = 8;
            serial.StopBits = StopBits.One;
            serial.Parity = Parity.None;
            serial.ReadTimeout = 100;
            serial.WriteTimeout = -1;
            serial.ReceivedBytesThreshold = 1;
            serial.DataReceived += new SerialDataReceivedEventHandler(Serial_Received);
            serial.Open();
}
//串口读数方法
        private void Serial_Received(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPort serial = (SerialPort)sender;

                string strReadData = serial.ReadExisting().Substring(3);
                string strWeight = null;
                this.Invoke(new Action(() =>
                {
                    for (int i = 0; i <= 16; i++)
                    {
                        if (strReadData.Substring(0, 1) == " ")
                        {
                            strReadData = strReadData.Substring(1);
                        }
                        else
                        {
                            if (i < 11)
                            {
                                strWeight = strWeight + strReadData.Substring(0, 1);
                                strReadData = strReadData.Substring(1);
                            }
                        }
                    }
                    txtNowWeight.Text = strWeight;
                }));
            }
            catch
            {
                MessageBox.Show("程序遇到一个无法处理的未知错误,请重新启动程序!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
//上传数据的方法,在执行操作中调用
 private void SendWeightData(string strNo, string strData, string strPlan, string strWeight, List<string> strPicture)
        {
            try
            {
              //因为安全问题,服务器信息都隐掉了
                factory = new ConnectionFactory();
                factory.HostName = "";//主机名
                factory.Port = 5672;
                factory.UserName = "";     //用户名
                factory.Password = "";//密码

                factory.AutomaticRecoveryEnabled = true;//自动的错误恢复机制

                SendMessage SMessage = new SendMessage();
                SMessage.NO = strNo;
                SMessage.Date = strDate;
                SMessage.Plan = strPlan;
                SMessage.Weight = strWeight;
                SMessage.Picture = strPicture;

                string jsontext = JsonConvert.SerializeObject(SMessage);

                //连接服务器,即正在创建终结点。
                using (var connection = factory.CreateConnection())//断点调试的过程中程序就卡在这一步
                {
                    using (var channel = connection.CreateModel())
                    {
                        var strProperties = channel.CreateBasicProperties();
                        channel.BasicPublish("交换机", "队列名", strProperties, Encoding.UTF8.GetBytes(jsontext)); //生产消息
                    }
                }
            }
            catch
            {
                throw;
            }

        }
请懂的大拿不吝赐教,如有未阐述明白的地方请联系我补充
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-11-01 05:40
    关注

    【以下回答由 GPT 生成】

    首先,问题的原因是在上传数据至队列期间关闭串口导致连接服务器的过程超时并报错。另外,有时候程序也会卡顿假死。以下是优化代码的建议:

    1. 避免在上传数据之前关闭串口,而是在上传完成后再关闭。可以在代码的适当位置添加关闭串口的代码,例如在Btn_Send_Click事件的最后。

    2. 引入多线程或异步编程来单独处理串口读取和数据上传的任务。这样可以避免阻塞UI线程,提高程序的响应性。

    3. 使用合适的同步机制来确保在上传数据时不会进行串口读取操作,例如使用锁、互斥量等。

    下面是优化后的伪代码示例:

    // 定义一个对象用于线程同步
    private object lockObj = new object();
    // 定义一个标志用于判断是否上传数据
    private bool isUploading = false;
    
    private void Menu_Load(object sender, EventArgs e)
    {
        // 初始化串口设置...
    
        // 开启一个新的线程用于串口读取
        Task.Run(() => Serial_Reading());
    }
    
    private void Serial_Reading()
    {
        while (true)
        {
            try
            {
                // 读取串口数据并处理...
            }
            catch (Exception ex)
            {
                // 处理异常...
            }
        }
    }
    
    private void Btn_Send_Click(object sender, EventArgs e)
    {
        if(!isUploading)
        {
            // 设置标志位为上传中
            isUploading = true;
    
            // 开启一个新的线程用于数据上传
            Task.Run(() =>
            {
                lock (lockObj)
                {
                    try
                    {
                        // 执行数据上传至队列的操作...
                    }
                    catch (Exception ex)
                    {
                        // 处理异常...
                    }
                    finally
                    {
                        // 设置标志位为上传完成
                        isUploading = false;
                    }
                }
            });
        }
        else
        {
            // 已经在上传数据,提示用户稍后再试或者禁用按钮等处理...
        }
    }
    
    private void Form_Closed(object sender, FormClosedEventArgs e)
    {
        // 关闭串口
        if (serial.IsOpen)
        {
            serial.Close();
        }
    }
    

    这样,串口读取与数据上传的任务将在不同的线程中执行,可以避免发生冲突。锁和标志位可以控制同一时间只能进行串口读取或数据上传的操作,以确保任务的正确执行。在关闭程序时,需要确保关闭串口以释放资源。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月20日
  • 已采纳回答 3月12日
  • 创建了问题 10月31日

悬赏问题

  • ¥15 java代码写在记事本上后在cmd上运行时无报错但又没生成文件
  • ¥15 关于#python#的问题:在跑ldsc数据整理的时候一直抱这种错误,要么--out识别不了参数,要么--merge-alleles识别不了参数(操作系统-linux)
  • ¥15 PPOCRLabel
  • ¥15 混合键合键合机对准标识
  • ¥100 现在不懂的是如何将当前的相机中的照片,作为纹理贴图,映射到扫描出的模型上
  • ¥15 魔霸ROG7 pro,win11.息屏后会显示黑屏,如图,如何解决?(关键词-重新启动)
  • ¥15 有没有人知道这是哪里出了问题啊?要怎么改呀?
  • ¥200 C++表格文件处理-悬赏
  • ¥15 Windows Server2016本地登录失败
  • ¥15 复合卡卡号轨道写入芯片卡