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

news2024/11/25 1:57:17

背景

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.coloradmin.cn/o/1830184.html

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

相关文章

微信小程序开发系列(三十五)·自定义组件的属性properties

微信小程序开发系列&#xff08;三十四&#xff09;自定义组件的创建、注册以及使用&#xff08;数据和方法事件的使用&#xff09;_wx小程序组件开发-CSDN博客 目录 1. 组件的属性 2. 组件的使用 3. 细节描述 1. 组件的属性 Properties是指组件的对外属性&#xff0c;主…

Nginx之静态文件服务器的搭建

1.概述 静态文件服务器是指提供HTML文件访问或客户端 可直接从中下载文件的Web服务器。对于图片、 JavaScript或CSS文件等渲染页面外观的、不会动态改 变内容的文件&#xff0c;大多数网站会单独提供以静态文件服 务器的方式对其进行访问&#xff0c;实现动静分离的架构。 HTML…

ReactNative和Android通信

初始化一个RN项目以后&#xff0c;接下来想要让Android与React Native通信 写一个继承自ReactContextBaseJavaModule类的子类&#xff0c;重写getName方法 package com.awesomeprojectimport android.util.Log import android.widget.Toast import com.facebook.react.bridge.…

Java并发自测题

文章目录 一、什么是线程和进程?线程与进程的关系,区别及优缺点&#xff1f;二、为什么要使用多线程呢?三、说说线程的生命周期和状态?四、什么是线程死锁?如何预防和避免线程死锁?五、synchronized 关键字六、并发编程的三个重要特性七、JMM &#xff08;Java Memory Mod…

Android 自定义View

我们所有的试图都是起源于自定义View&#xff0c;包括ViewGroup也是继承于它&#xff0c;可以说它是视图组件之父。 我们可以从它的大致流程来分为四个部分&#xff1a; 构造方法&#xff0c;onMeasure&#xff0c;onLayout&#xff0c;onDraw 构造方法&#xff1a; 它主要有…

Java | Leetcode Java题解之第160题相交链表

题目&#xff1a; 题解&#xff1a; public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA null || headB null) {return null;}ListNode pA headA, pB headB;while (pA ! pB) {pA pA null ? headB : pA.next;pB …

Springmvc接收请求参数

如果你觉得这种限制很麻烦&#xff0c;你可以改为String 因为所有参数在接收的时候原值都是字符串

Mac | 崩溃分析

一、dump分析 1. 导入符号&#xff1a; ./import_pdb.sh libmedia_stream_ext.dylib.dSYM ./import_pdb.sh libowcr.framework.dSYM 2. 分析dump&#xff1a; ./analyze_dump.sh AE59D64F-0E1D-4A18-8DAF-C2C4D22F9FA6.dmp 3. 第 2 步骤 中会输出崩溃模块、崩溃线程及堆栈…

使用 Python 进行测试(5)测试的类型

总结 和我一起唱&#xff01; 冒烟测试&#xff0c;让你快速失败&#xff1b; 回归测试&#xff0c;不打破过去&#xff1b; 健全性检查&#xff0c;保留所拥有&#xff1b; 集成测试&#xff0c;处理副作用&#xff1b; 端到端&#xff0c;永无尽头&#xff01; 回测&#xf…

SwiftUI 6.0(Xcode 16)全新 @Entry 和 @Previewable 宏让开发妙趣横生

概览 如火如荼的 WWDC 2024 已进入第五天&#xff0c;苹果开发平台中众多海量新功能都争先恐后的喷薄欲出。 在这里就让我们从中挑两个轻松有趣的新功能展示给小伙伴们吧&#xff1a;它们分别是 全新的 Entry 和 Previewable 宏。 在本篇博文中&#xff0c;您将学到如下内容&a…

用React编写一个密码组件表单

theme: condensed-night-purple highlight: atelier-cave-light 背景介绍 我们在使用网站或者应用程序的登录界面或创建帐户界面时&#xff0c;往往避免不了需要用户输入密码这一步骤&#xff0c;而用户是否可以选择看见他们输入的密码是十分重要的一项功能。尤其是在当输入的…

Focusky是什么软件

Focusky是一款基于HTML5技术的多媒体演示软件&#xff0c;可以轻松地制作出生动有趣的PPT演示文稿、动画宣传片以及微课。与其他软件相比&#xff0c;Focusky拥有丰富的多媒体资源和动画效果&#xff0c;可以让演示内容更加生动。本文将为您详细介绍Focusky软件的功能&#xff…

awd工具安装

fscan(漏洞扫描) 下载 下载地址: Releases shadow1ng/fscan GitHub 把下载的文件放到指定文件目录里, 在文件的位置打开cmd 输入 fscan64.exe -h 192.168.1.1/24 ok了 接下来说说fscan的使用 使用 1.信息搜集: 存活探测(icmp) 端口扫描 2.爆破功能: 各类服务爆破(…

MongoDB~高可用集群介绍:复制集群(副本集)、分片集群

背景 MongoDB 的集群主要包括副本集&#xff08;Replica Set&#xff09;和分片集群&#xff08;Sharded Cluster&#xff09;两种类型。 副本集 组成&#xff1a;通常由一个主节点&#xff08;Primary&#xff09;和多个从节点&#xff08;Secondary&#xff09;构成。 功…

UniVue更新日志:使用ObservableList优化LoopList/LoopGrid组件的使用

github仓库 稳定版本仓库&#xff1a;https://github.com/Avalon712/UniVue 开发版本仓库&#xff1a;https://github.com/Avalon712/UniVue-Develop UniVue扩展框架-UniVue源生成器仓库&#xff1a;https://github.com/Avalon712/UniVue-SourceGenerator 更新说明 如果大家…

Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

【java】数学运算考试系统

目录 一、登录界面&#xff1a; 二、管理员界面&#xff1a; 三、学生考试界面&#xff1a; 面向小学低年级学生&#xff0c;随机生成两个整数的加减法算式要求学生解答。要求有用 户登录、注册等 GUI 界面&#xff0c;用户数据存入文件&#xff0c;体现面向对象编程思想。 …

windows11子系统Ubuntu 22.04.4子安装图形化界面

1、windows11家庭版本设置 打开虚拟机安装许可 2、Microsoft Store下载安装ubuntu 我使用的是22.04.4 LTS版本 3、 打开ubuntu 命令窗口 1、打开win11的命令行&#xff0c;在下拉三角下标&#xff0c;打开&#xff0c;可以看到有Ubuntu 的选项&#xff0c;点击即可进入linux命…

【Android面试八股文】你说一说什么是双亲委托机制?为什么需要双亲委托机制?

一、双亲委托机制 1.1 双亲委托机制概述 双亲委托机制是指当一个类加载器收到一个类加载请求时, 该类加载器首先会把请求委派给父类加载器。 如果父类加载器还存在父类加载器,则会一直向上委派,直至最终交由顶层的启动类加载器完成类加载, 每个类加载器都是如此,只有在所…

RIP解决不连续子网问题

#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网&#xff0c;被另一个主网分割&#xff0c;例如下面实验拓扑在某公司的网络整改项目中&#xff0c;原先R1 和RS 属于同一主网络 10.0.0.0/8&#xff0c;现被 R2、R3、R4 分离&#xff0c;整网采用了 …