You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中没有对应的注册项,消息就会无人接收。第二次点击时接收端已完成注册,所以能正常接收。
解决方法
  1. 修正拼写错误
    把构造函数名改成public ReceiverClass(),把sting receivedMessage;改成string receivedMessage;,确保接收端的初始化和注册逻辑能正常执行。

  2. 确保接收端先完成注册
    保证ReceiverClass的实例在首次发送消息之前就已经创建并完成了WeakReferenceMessenger的注册。比如如果是导航到Sender页面后才创建Receiver页面,首次发送时Receiver还未初始化,就收不到消息。可以提前初始化Receiver实例,或者在Receiver页面加载完成后再允许触发发送逻辑。

  3. 排查弱引用生命周期问题(可选)
    如果怀疑是弱引用被提前回收,可以临时在注册时设置keepAlive: true强制保持引用:

    WeakReferenceMessenger.Default.Register<SenderClass.SendString>(this, keepAlive: true, (r, m) =>
    {
        OnStringReceived(m.Value);
    });
    

    但这只是临时排查手段,不建议长期使用,核心还是要梳理好页面实例的生命周期,确保接收端在消息发送时处于活跃状态。


内容的提问来源于stack exchange,提问作者Costas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:12:39