C# 串口通讯之艰难排错之路 —— system.ObjectDisposedException已关闭 Safe handle

今天写了一个串口通讯扫码枪驱动,程序运行后,不出意外的全线崩溃,开始了漫长的排查之旅,具体情况报错如下:

复制代码
解决未处理 System.ObjectDisposedException
Message=已关闭 Safe handle
Source=mscorlib
ObjectName=""
StackTrace:
在 System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
在 System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
在 Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
在 System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()

真的真的很无语,程序正常跑了一会,也能捉到数据,突然它就中风了,数据捉不到了,也没有任何报错。

逼不得已程序重新解包重装,到处打断点一步一步调试。最后发现当这个BUG出现时,程序直接崩溃,无法跟踪到错误代码位置。

最后意识到SerialPort类引起的问题,可能是在已释放的SerialPort对象上尝试进行操作导致的问题。

  1. 思路一:
  • 为了解决这个问题,可以在使用完SerialPort对象后,确保正确地释放和关闭它。
  • 但是呀,我的是扫码枪啊,串口必须一直打开,怎么可能关闭它,于是这个方案立马放弃。
  1. 思路二:
  • 我在使用SerialPort的时候可以检查它的状态呀确保在处理数据之前,串口仍然处于打开状态。这样可以避免在已关闭的串口上进行操作,从而减少System.ObjectDisposedException异常的发生。

  • 说干就干,代码增加一行 if 判断:

    if (!serialPort.IsOpen)
    {
    serialPort.Open();
    }

  1. 思路三:
  • 在一个函数内利用SerialPort创建了串口通信实例后,没有将该实例放入任何其他容器中进行缓存,从而也会导致了上述崩溃BUG的产生。

  • 那我就修改代码:将该实例放入了一个全局变量List<通信客户端>集合,下面的代码分别放到对应位置就行。

    //这个作为全局变量就声明创建
    public List<SerialPort> PortModels = new List<SerialPort>();

    //这个在实例化对象后封装
    PortModels.Add(SerialPort);/

哈哈哈,经过以上几步该BUG终于得以解决,家人们高歌万岁吧!!!

相关推荐
一只小bit4 小时前
Qt 快速开始:安装配置并创建简单标签展示
开发语言·前端·c++·qt·cpp
wadesir4 小时前
深入理解Rust静态生命周期(从零开始掌握‘static的奥秘)
开发语言·后端·rust
+VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue零食商城管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
是有头发的程序猿4 小时前
Python爬虫实战:面向对象编程在淘宝商品数据抓取中的应用
开发语言·爬虫·python
yyycqupt4 小时前
蓝牙协议栈的学习(二)
stm32·单片机·嵌入式硬件·mcu·物联网·51单片机·iot
丁丁丁梦涛4 小时前
EMQX配置 ssl 和 wss
网络·网络协议·ssl·emqx·wss
哈哈哈笑什么4 小时前
蜜雪冰城1分钱奶茶秒杀活动下,使用分片锁替代分布式锁去做秒杀系统
redis·分布式·后端
Query*4 小时前
杭州2024.08 Java开发岗面试题分类整理【附面试技巧】
java·开发语言·面试
WZTTMoon5 小时前
Spring Boot 4.0 迁移核心注意点总结
java·spring boot·后端