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");

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在3天内开发一个鸿蒙app

华为鸿蒙操作系统&#xff08;HarmonyOS&#xff09;自2.0版本正式上线以来&#xff0c;在短时间内就部署超过了2亿台设备&#xff0c;纵观全球操作系统的发展史&#xff0c;也是十分罕见的。与其他手机操作系统不同&#xff0c;HarmonyOS自诞生之日起&#xff0c;就是一款面向…

【C++取经之路】继承

目录 继承的概念及定义 单继承的格式 继承方式和访问限定符 继承后子类访问基类成员的权限 基类和派生类对象赋值转换 切片 继承中的作用域 引申&#xff1a;重载和隐藏的区别 派生类的默认成员函数 继承与友元 继承与静态成员 如何实现一个不能被继承的类 复杂的…

【Java】解决Java报错:IllegalStateException during HTTP Request

文章目录 引言一、IllegalStateException的定义与概述1. 什么是IllegalStateException&#xff1f;2. IllegalStateException在HTTP请求中的常见触发场景3. 示例代码 二、解决方案1. 确保响应只被提交一次2. 正确管理Servlet的生命周期3. 避免重复访问输入流和输出流4. 使用框架…

HTML静态网页成品作业(HTML+CSS)—— 名人霍金介绍网页(6个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 二、作品演示 三、代…

vscode切换Python解释器

在vscode上切换解析器解决方案&#xff1a; 1、确认自己已经安装了python环境 2、command shift p ,在这里切换即可&#xff0c;见下图&#xff1a; 3、如果状态栏也就是右下角不现实切换操作的话&#xff0c;打开设置&#xff1a;

【六】Linux安装部署Nginx web服务器--及编写服务器启动脚本

一、部署安装nginx 1、查看nginx是否安装依赖包 [rootlocalhost ~]# rpm -q zlib-devel pcre-devel package zlib-devel is not installed package pcre-devel is not installed 2、若没有则安装nginx 依赖包 [rootlocalhost ~]# yum -y install zlib-devel* pcre-dev…

01 Pytorch 基础

paddle不需要放数据到gpu&#xff01; 区别&#xff1a;1.batch_norlization 不同 2. 1.数据处理 1.取一个数据&#xff0c;以及计算大小 &#xff08;剩下的工作&#xff0c;取batch&#xff0c;pytorch会自动做好了&#xff09; 2.模型相关 如何得到结果 3.模型训练/模型…

6月13日 Qtday1

#include "mywidget.h" //腾讯会议的登录界面 MyWidget::MyWidget(QWidget *parent): QMainWindow(parent) {this->setFixedSize(468,830);//主窗口大小this->setStyleSheet("background-color:rgb(255,255,255)");//主窗口背景this->setWindowTi…

Oxlint 会取代 Eslint 吗?

最近&#xff0c;一个基于 Rust 的代码检查工具 Oxlint 在国外前端社区引起了热议&#xff0c;许多专家对其给予了高度评价。那么&#xff0c;相比于它的大哥 Eslint&#xff0c;Oxlint 有哪些优势&#xff1f;它会在未来取代 Eslint 吗&#xff1f;本文将讨论这个话题。 Oxc 和…

现货黄金投资价格怎么分析 低买高卖是核心!

我们做现货黄金投资&#xff0c;总是离不开对黄金价格的分析&#xff0c;分析其实就是一种理性的思考&#xff0c;我们对现货黄金当前走势进行一番思考&#xff0c;进而判断它未来的走向&#xff0c;以此作为自己投资入场的基础。那黄金投资价格怎么分析呢&#xff1f;下面我们…

uniapp开发微信小程序预加载分包

微信小程序分包是一种优化小程序项目结构和性能的方式。它允许开发者将小程序代码包拆分成多个子包&#xff0c;在用户需要时动态加载这些子包&#xff0c;从而减少小程序的首次加载时间和主包的体积。&#xff08;总体积不得大于20M&#xff0c;主包&#xff08;共同文件静态资…

Matlab|基于主从博弈的智能小区代理商定价策略及电动汽车充电管理

目录 一、主要内容 二、部分代码 三、程序结果 四、下载链接 一、主要内容 主要做的是一个电动汽车充电管理和智能小区代理商动态定价的问题&#xff0c;将代理商和车主各自追求利益最大化建模为主从博弈&#xff0c;上层以代理商的充电电价作为优化变量&#xff0c;下层以…

Java I/O模型

引言 根据冯.诺依曼结构&#xff0c;计算机结构分为5个部分&#xff1a;运算器、控制器、存储器、输入设备、输出设备。 输入设备和输出设备都属于外部设备。网卡、硬盘这种既可以属于输入设备&#xff0c;也可以属于输出设备。 从计算机结构的视角来看&#xff0c;I/O描述了…

在 Kubernetes 上拉取 Harbor 私有仓库镜像并部署服务

上一篇讲解了IntelliJ IDEA和Jib Maven插件配合&#xff0c;镜像一键推送到Harbor私服仓库&#xff0c;今天来讲解下怎么让k8s直接拉取Harbor 私有仓库上面的镜像 创建 Kubernetes Secret 用于拉取镜像 因为 Harbor 仓库是私有的&#xff0c;我们需要创建一个 Kubernetes Sec…

JavaScript面向对象

一、编程思想 面向过程介绍 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些一步一步实现&#xff0c;使用的时候再一个一个依次调用就可以了。 面向过程&#xff0c;就是按照我们分析好了的步骤&#xff0c;按照步骤解决问题。 面向对象编程&#xf…

阻抗控制(Impedance Control)和导纳控制(Admittance Control)例子

阻抗控制(Impedance Control)和导纳控制(Admittance Control) 是两种用于机械臂或机器人交互控制的策略。阻抗控制定义的是机器人端部的力和位置之间的关系,而导纳控制则定义的是外力和运动之间的关系。导纳控制常用于处理机器人与环境交互中的力控制问题。 适用场景对比…

185.二叉树:二叉搜索树的最近公共祖先(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class Solution { public:// 函数用于寻找二叉搜索树中节点 p 和 q 的最低…

Honor of Kings 2024.06.13 (2)

【第一局】准确的说&#xff0c;其实对面优势更加明显&#xff0c;可惜黄忠和墨子喜欢杀人&#xff0c;而我又是不喜欢杀人的&#xff0c;打了好几次失误 【第二局】阵容本来很有优势&#xff0c;这个二呆射手跟第一局黄忠一样爱杀人&#xff0c;应该说三路的输出都爱杀人&…

小主机折腾记26

双独立显卡调用问题 前两天将tesla p4从x99大板上拆了下来&#xff0c;将880G5twr上的rx480 4g安装到了x99大板上&#xff0c;预计是dg1输出&#xff0c;rx480做3d运算。安装完驱动后&#xff0c;还想着按照之前tesla p4的设置方法去设置rx480&#xff0c;结果果然&#xff0c…

Serverless 使用OOS将http文件转存到对象存储

目录 背景介绍 系统运维管理OOS 文件转存场景 前提条件 实践步骤 附录 示例模板 背景介绍 系统运维管理OOS 系统运维管理OOS&#xff08;CloudOps Orchestration Service&#xff09;提供了一个高度灵活和强大的解决方案&#xff0c;通过精巧地编排阿里云提供的OpenAPI…