WINUI——CommunityToolkit.Mvvm Messenger接收消息时报错:Cannot access a disposed object.

背景

WINUI开发时使用CommunityToolkit.Mvvm的Messemger让UI展示一些信息时出现错误:

System.ObjectDisposedException:“Cannot access a disposed object.
ObjectDisposed_ObjectName_Name”

详细见下述截图:

开发环境

WIN11

WINUI3

CommunityToolkit.Common 7.1.2

原因探究

AI给出的产生原因

在 C# 中使用 WeakReferenceMessenger(或者类似的弱引用消息传递机制)时,遇到 System.ObjectDisposedException 异常通常意味着你尝试访问了一个已经被释放(disposed)的对象。在 MVVM 架构中,这通常发生在视图模型(ViewModel)或视图(View)的生命周期管理不当的情况下。

在 WinUI(或任何 UI 框架)中,当视图(或页面)被卸载或关闭时,与其关联的视图模型(或数据上下文)可能也会被释放。如果你在这些对象被释放后仍然尝试通过消息传递机制(如 WeakReferenceMessenger)与它们通信,就可能会遇到 ObjectDisposedException

为了解决这个问题,你需要在适当的时候注销(Unregister)你的消息接收器。在 WinUI 中,这通常意味着在视图或视图模型被释放之前,你需要调用 Unregister 方法来取消注册你的消息处理器。

以下是一些可能的解决方案:

  1. 在视图模型中注销
    在视图模型的 OnNavigatedFrom 方法(如果你使用的是导航框架)或相应的生命周期事件中,确保调用 Unregister 方法来取消注册消息处理器。

  2. 使用 IDisposable 接口
    实现 IDisposable 接口并在 Dispose 方法中注销消息处理器。这样,当视图模型被垃圾回收或显式释放时,消息处理器也会被自动注销。

  3. 使用弱引用
    虽然 WeakReferenceMessenger 已经使用了弱引用来减少内存泄漏的风险,但确保你的消息处理器不会持有对即将被释放对象的强引用也是很重要的。

  4. 检查消息传递的时机
    确保在视图或视图模型仍然有效时发送消息。如果可能的话,避免在视图或视图模型的生命周期之外发送消息。

  5. 使用调试工具
    使用调试工具(如 Visual Studio 的诊断工具)来跟踪对象的生命周期和内存使用情况,这有助于识别何时何地对象被释放以及为何会出现 ObjectDisposedException

  6. 查看文档和示例
    查阅 MVVM Toolkit 的文档和示例代码,看看是否有关于如何正确使用 WeakReferenceMessenger 的最佳实践和推荐做法。

以上是AI给出的一些建议,至于它说提到的原因,更觉得是有些扯淡。因为消息接收是在Page页直接接收相应的消息,同时将接收到的文本显示在Page上的Button上,而这个Page正是当前在使用的页面,那么也就是说不存在它所说的访问了一个已经被释放(disposed)的对象

猜想:可能的真实原因

此很可能是由于Toolkit的bug或WINUI的Bug所致,但更大可能是Toolkit的bug导致了上述问题,因为在后续的测试中,假设是由于对象被释放时产生的问题,那么Messenger还在接收信息,那么肯定是会出现Cannot access a disposed object.(不能进入释放对象)这个错误的。然Page是肯定没有释放的,那么对象没有释放,会不会是它注册到Messenger内的对象除了当前的这个Page还有一个之前的当前Page呢?而之前的当前Page在再次进入这个Page时肯定是会被回收了,而Messenger内的未被回收,于是就可能导致这个问题的产生……

解决方法

虽然否定了AI给出的解释,但是它提到的:

在 WinUI(或任何 UI 框架)中,当视图(或页面)被卸载或关闭时,与其关联的视图模型(或数据上下文)可能也会被释放。如果你在这些对象被释放后仍然尝试通过消息传递机制(如 WeakReferenceMessenger)与它们通信,就可能会遇到 ObjectDisposedException

按上述说法,也就是说只要将注册的Messenger取消注册即可。

注册与取消注册

在VM/发送位置中注册:

  WeakReferenceMessenger.Default.Register<string, string>(this, $"token", (r, msg) => YourAction);

Page/接收位置取消注册:

  WeakReferenceMessenger.Default.Unregister<string, string>(this, $"token");

按上述操作操作后,再重新生成整个解决方案,确实是解决了问题。

也就是原来的猜想是有点靠谱。先留下此坑,后续待完全弄懂此问题原因,再更新或重开文章说明真正的原因,以解决此困惑,否则它将成为手中刺一样,不时让人痛苦一下,很是让人难受。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/706043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【源码】html+JS实现:24小时折线进度图

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>24小时折线进度图</title> <st…

代码生成-CodeGeeX2本地部署体验

一 CodeGeeX2介绍&#xff1a; CodeGeeX2 是多语言代码生成模型 CodeGeeX (KDD’23) 的第二代模型。不同于一代 CodeGeeX&#xff08;完全在国产华为昇腾芯片平台训练&#xff09; &#xff0c;CodeGeeX2 是基于 ChatGLM2 架构加入代码预训练实现&#xff0c;得益于 ChatGLM2 的…

是否可以购买外链?

答案是可以&#xff0c;但要看你买什么外链&#xff0c;有价值的自然外链价格肯定也高&#xff0c;随便到某些平台发的外链&#xff0c;哪怕是相关的高权重平台&#xff0c;作用也有限&#xff0c;当然&#xff0c;你要大批量购买&#xff0c;说不定也能出一点效果&#xff0c;…

天诚公租房、人才公寓NB-IOT人脸物联网智能门锁解决方案

近期&#xff0c;全国已有超70城推出商品房“以旧换新”。各地商品房“以旧换新”主要采取国企收购、市场联动、税费补贴三种模式&#xff0c;二手房和新房市场交易活跃度均有提升。 一、人才公寓掀起建设浪潮 事实上&#xff0c;旧房被收购后将被纳入保障性租赁住房&#xf…

opencv 通过滑动条调整阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强参数 并实时预览效果

使用PySimpleGUI库创建了一个图形用户界面(GUI),用于实时处理来自OpenCV摄像头的图像。它允许用户应用不同的图像处理效果,如阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强。用户可以通过滑动条调整相关参数。 完整代码在文章最后,可以运行已经测试; 代码的…

代码随想录Day58

392.判断子序列 题目&#xff1a;392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;定义重合数记录s与t的比对情况&#xff0c;挨个取出t的字符&#xff0c;与s的字符进行比较&#xff0c;如果相同&#xff0c;重合数就加1&#xff0c;跳到s的下一个字…

QStyledItemDelegate的使用方法

QStyledItemDelegate 是 Qt 框架中用于为模型/视图框架提供数据项显示和编辑的一个类。 1. 创建 QStyledItemDelegate 实例 通常&#xff0c;你不需要直接实例化 QStyledItemDelegate&#xff0c;因为它是默认的委托。但如果你需要自定义显示和编辑行为&#xff0c;你可以继承…

韩顺平0基础学java——第22天

p441-459 异常exception 选中代码块&#xff0c;快捷键ctraltt6&#xff0c;即trt-catch 如果进行了异常处理&#xff0c;那么即使出现了异常&#xff0c;但是会继续执行 程序过程中发生的异常事件分为两大类&#xff1a; 异常体系图※ 常见的运行异常&#xff1a;类型转换…

继承深度剖析

前言 从继承开始就开始C进阶了&#xff0c; 这一块需要好好学习&#xff0c;这块知识很重要&#xff0c; 坑有点多&#xff0c;所以是面试笔试的常客。 基本概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c; 它允许程序员在保持原有…

使用MNIST数据集训练手写数字识别模型

一、MNIST数据集介绍 MNIST 数据集&#xff08;手写数字数据集&#xff09;是一个公开的公共数据集&#xff0c;任何人都可以免费获取它。目前&#xff0c;它已经是一个作为机器学习入门的通用性特别强的数据集之一&#xff0c;所以对于想要学习机器学习分类的、深度神经网络分…

抓包工具 Wireshark 的下载、安装、使用、快捷键

目录 一、什么是Wireshark&#xff1f;二、Wireshark下载三、Wireshark安装四、Wireshark使用4.1 基本使用4.2 过滤设置1&#xff09;捕获过滤器2&#xff09;显示过滤器 4.3 过滤规则1&#xff09;捕获过滤器-规则语法2&#xff09;显示过滤器-规则语法 4.4 常用的显示过滤器规…

js实现一个数据结构——栈

栈的概念就不再赘述&#xff0c;无可厚非的先进后出&#xff0c;而JS又是高级语言&#xff0c;数组中的方法十分丰富&#xff0c;已经自带了push pop方法进行入栈出栈的操作。 1.基本实现 class Stack {constructor() {this.items [];}// 入栈push(item) {this.items.push(i…

【C++入门(1)】命名空间

一、C出世 我们先简单认识下C的来历&#xff0c;C是在C语言的基础上发展来的。 当年C的设计者Bjarne Stroustrup&#xff0c;本贾尼斯特劳斯特卢普先生设计C语言之初&#xff0c;是为了对C语言做出一些更改&#xff0c;弥补C语言在一些方面的不足&#xff0c;或者做出其他的设…

二阶段提交(2pc)协议

二阶段提交&#xff08;2pc&#xff09;协议 1、 简介 二阶段提交算法是一个分布式一致性算法&#xff0c;强一致、中心化的原子提交协议&#xff0c;主要用来解决分布式事务问题。在单体spring应用中我们往往通过一个Transactional注解就可以保证方法的事务性&#xff0c;但…

破解发展难题 台山这家合作社以农业社会化服务助推乡村振兴

风吹稻田千层浪&#xff0c;眼下&#xff0c;台山四九镇的早稻长势喜人&#xff0c;沉甸甸的稻穗迎风而动&#xff0c;已进入破口抽穗的关键期&#xff0c;即将在6月底陆续迎来丰收。在台山市明华汇种养专业合作社管理的稻田里&#xff0c;合作社负责人梁明喜正仔细观察着稻苗的…

算法第六天:力扣第977题有序数组的平方

一、977.有序数组的平方的链接与题目描述 977. 有序数组的平方的链接如下所示&#xff1a;https://leetcode.cn/problems/squares-of-a-sorted-array/description/https://leetcode.cn/problems/squares-of-a-sorted-array/description/ 给你一个按 非递减顺序 排序的整数数组…

#慧眼识模每日PK[话题]##用五种语言说爸爸我爱你[话题]#

#慧眼识模每日PK #用五种语言说爸爸我爱你 你觉得哪个模型回答得更好&#xff1f;欢迎留言 A.蓝 B.紫 更多问题&#xff0c;扫码体验吧&#xff5e; by 国家&#xff08;杭州&#xff09;新型交换中心

Whisper语音识别 -- 自回归解码分析

前言 Whisper 是由 OpenAI 开发的一种先进语音识别系统。它采用深度学习技术&#xff0c;能够高效、准确地将语音转换为文本。Whisper 支持多种语言和口音&#xff0c;并且在处理背景噪音和语音变异方面表现出色。其广泛应用于语音助手、翻译服务、字幕生成等领域&#xff0c;为…

鸿蒙轻内核A核源码分析系列七 进程管理 (3)

本文记录下进程相关的初始化函数&#xff0c;如OsSystemProcessCreate、OsProcessInit、OsProcessCreateInit、OsUserInitProcess、OsDeInitPCB、OsUserInitProcessStart等。 1、LiteOS-A内核进程创建初始化通用函数 先看看一些内部函数&#xff0c;不管是初始化用户态进程还…

收银系统小程序商城商品详情页再升级!

本期导读 1.新增&#xff1a;商品详情页新增商品参数模块&#xff1b; 2.新增&#xff1a;商品详情页新增保障服务模块&#xff1b; 3.新增&#xff1a;线上商城商品新增划线价&#xff1b; 4.新增&#xff1a;线上商城分销商品新增“赚”字标签及预收收益&#xff1b; 5.…