WeakReferenceMessenger首次消息未被接收问题及解决方法
问题
点击按钮使用WeakReferenceMessenger发送消息时,首次发送的消息无法被接收,从第二次点击开始一切正常。断点显示首次点击时发送逻辑正常执行,但接收端的消息处理方法未触发。
SenderClass.xaml.cs
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; namespace MyApp; public partial class SenderClass : ContentPage { public SenderClass() { InitializeComponent(); } public class SendString : ValueChangedMessage<string> { public SendString(string value) : base(value) { } } private async void OnButtonTapped(object sender, EventArgs e) { WeakReferenceMessenger.Default.Send(new SendString("A random string")); } }
ReceiverClass.xaml.cs
using CommunityToolkit.Mvvm.Messaging; namespace MyApp { public partial class ReceiverClass : ContentPage { public ReeceiverClass() // 拼写错误:ReeceiverClass -> ReceiverClass { InitializeComponent(); WeakReferenceMessenger.Default.Register<SenderClass.SendString>(this, (r, m) => { OnStringReceived(m.Value); }); } sting receivedMessage; // 拼写错误:sting -> string private void OnStringReceived(string myString) { receivedMessage = "Received message is:" + myString; } } }
原因分析
- 代码拼写错误:ReceiverClass的构造函数写成了
ReeceiverClass(多了一个e),导致构造函数无法正常执行,消息注册逻辑根本没有运行;另外sting是string的拼写错误,也会影响代码编译和运行。 - 实例生命周期问题:即使修正拼写错误,若首次发送消息时
ReceiverClass的实例还未完成初始化(或尚未被创建),WeakReferenceMessenger中没有对应的注册项,消息就会无人接收。第二次点击时接收端已完成注册,所以能正常接收。
解决方法
修正拼写错误
把构造函数名改成public ReceiverClass(),把sting receivedMessage;改成string receivedMessage;,确保接收端的初始化和注册逻辑能正常执行。确保接收端先完成注册
保证ReceiverClass的实例在首次发送消息之前就已经创建并完成了WeakReferenceMessenger的注册。比如如果是导航到Sender页面后才创建Receiver页面,首次发送时Receiver还未初始化,就收不到消息。可以提前初始化Receiver实例,或者在Receiver页面加载完成后再允许触发发送逻辑。排查弱引用生命周期问题(可选)
如果怀疑是弱引用被提前回收,可以临时在注册时设置keepAlive: true强制保持引用:WeakReferenceMessenger.Default.Register<SenderClass.SendString>(this, keepAlive: true, (r, m) => { OnStringReceived(m.Value); });但这只是临时排查手段,不建议长期使用,核心还是要梳理好页面实例的生命周期,确保接收端在消息发送时处于活跃状态。
内容的提问来源于stack exchange,提问作者Costas
相关产品推荐
相关产品推荐

