当前位置: 首页 > news >正文

代码关闭窗体报错原因及解决方案

System.ObjectDisposedException:”无法访问已释放的对象。 报错的根本原因!!!
1:对象生命周期的冲突
this.Invoke(...) 是在非 UI 线程(比如 PLC 通讯的后台线程、轮询线程)里,去更新 UI 控件。
关闭窗体时,控件会被.NET 自动释放(Dispose)。
但此时后台线程还在运行,它继续调用 this.Invoke 去访问已经被释放的窗体 / 控件,就会抛出这个异常。

2:为什么 Invoke 也会炸?
很多人以为用了 Invoke 就安全了,但它只是解决了 “跨线程访问 UI” 的问题,解决不了 “对象已经被释放” 的问题。
窗体被释放后,它的句柄(Handle)已经无效,Invoke 会尝试向一个已经不存在的窗口发送消息,最终触发这个异常。

方案:线程安全的关闭逻辑(工控项目首选)
在窗体的 FormClosing 事件里,主动停止后台线程,再等待线程退出,避免它在窗体释放后继续执行。
// 定义一个线程安全的停止标志
private CancellationTokenSource cts = new CancellationTokenSource();

// 你的后台轮询/通讯线程里,加入停止判断
private void CommunicationThread()
{
while (!cts.IsCancellationRequested)
{
// PLC读取逻辑...

    // 这里加个判断,没有释放和没有请求取消,再调用Invoke。if (!IsDisposed && !cts.IsCancellationRequested){this.Invoke(new Action(() =>{if (!IsDisposed) // 双重判断,防止窗体在Invoke排队期间被释放{//要更新UI的代码......}}));}Thread.Sleep(100); // 你的轮询间隔
}

}

/ 窗体关闭事件
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// 1. 先取消线程
cts.Cancel();

// 2. 等待线程退出(防止线程还在执行)
// 如果线程是Task,用Task.WaitAll();如果是Thread,用Thread.Join();单位毫秒。
// 注意:这里不能用无限等待,避免死锁,可以加超时
// communicationThread.Join(1000); // 3. 释放资源
cts.Dispose();

}

用 IsHandleCreated 比 IsDisposed 更可靠
窗体刚创建时 IsDisposed 是 false,但句柄还没创建,此时调用 Invoke 也会报错,所以判断 IsHandleCreated 更严谨。
工控项目里最稳妥的写法,就是先停线程,再关窗体,再在 Invoke 里加判断。

http://www.jsqmd.com/news/551627/

相关文章:

  • 效率提升:用快马平台将origin绘图流程模板化,一键生成论文级图表
  • Rivets.js实际项目案例:构建电商应用的数据绑定架构
  • Problems 复数 5
  • Umi-OCR:本地化高效识别与全场景应用指南
  • SDL2窗口自适应实战:解决视频卡顿与分辨率切换崩溃问题(附完整代码)
  • Kindle党必备技能:5分钟搞定批量Markdown转MOBI(含多文件合并攻略)
  • 告别模拟音频线!用MAX98357A数字功放芯片,5分钟搞定I2S直连ESP32播放MP3
  • 基于MATLAB的隔离型DC DC变换器系统设计:技术指标明确、包含设计报告与仿真程序的全过程解析
  • 金融风控实战:SMOTE、Borderline SMOTE与ADASYN在不平衡数据中的优化策略
  • 智能锁DIY全记录:用STM32F401RET6实现指纹+密码功能(附完整代码)
  • 工作总结-需要学习的方向
  • 颠覆式教育资源获取工具:智能解析技术重构电子课本下载体验
  • UE 5插件开发(二):Live Cording如何用?
  • Vue3-DateTime-Picker:如何让Vue 3应用的时间选择变得简单又优雅?
  • 从12MHz晶振到LED闪烁:用定时器中断实现51单片机精准1秒延时(附完整代码与计算过程)
  • ROS 2命令行工具实战指南:从系统监控到高效调试
  • Font-Awesome-SVG-PNG 跨平台部署:Windows、Mac、Linux完整教程
  • DeepSeek总结的postgresql数据库解决高并发查询性能问题的方法
  • VGGT代码文档自动生成终极指南:使用pdoc3快速构建专业API参考
  • Squeezer性能优化指南:提升dApp响应速度的7个技巧
  • Cortex-R52系统控制寄存器:从架构解析到实战访问
  • 如何让AI编程助手真正懂你?揭秘OpenCode插件系统的定制化魔力
  • NSLogger高级过滤技巧:正则表达式实战指南
  • HFS插件开发入门:从零开始创建自定义功能
  • 精锐纵横营销顾问——以全链路实战能力迭代营销咨询行业
  • Font-Awesome-SVG-PNG 核心原理:深入解析SVG到PNG的转换机制
  • STM32静态库(.lib)实战:从源码到库文件,解决Keil编译中的那些‘坑’
  • Qwen2.5-VL-7B-Instruct保姆级:SSH远程部署+ngrok内网穿透共享演示
  • 记录一下Linux 6.12 中 cpu_util函数的作用
  • 造相-Z-Image-Turbo亚洲美女LoRA应用场景:短视频封面/公众号配图/营销素材生成