编辑
2025-11-25
C#
00

目录

简介
主要特点
基本使用方法
安装包
定义消息类
基本使用示例
高级用法
使用消息标记(Token)
使用消息处理器(Handler)
使用消息过滤器
注意事项
总结

简介

WeakReferenceMessenger 是 CommunityToolkit.Mvvm 库中提供的一个轻量级消息传递工具,它使用弱引用来存储消息接收者,可以有效防止内存泄漏。本文将详细介绍其使用方法和最佳实践。

主要特点

  • 使用弱引用存储接收者,避免内存泄漏
  • 支持强类型消息
  • 支持不同接收者接收同一类型消息
  • 支持消息过滤
  • 线程安全

基本使用方法

安装包

首先需要通过 NuGet 安装 CommunityToolkit.Mvvm 包:

Bash
dotnet add package CommunityToolkit.Mvvm

image.png

定义消息类

C#
// 定义一个简单的消息类 public class UserMessage { public string Content { get; } public UserMessage(string content) { Content = content; } }

基本使用示例

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; namespace App10 { public class MessageReceiver : IDisposable { public MessageReceiver() { // 注册消息接收 WeakReferenceMessenger.Default.Register<UserMessage>(this, OnMessageReceived); } private void OnMessageReceived(object recipient, UserMessage message) { Console.WriteLine($"收到消息: {message.Content}"); } // 记得在不需要时取消注册 public void Cleanup() { WeakReferenceMessenger.Default.Unregister<UserMessage>(this); } // 实现 IDisposable 接口,确保正确清理资源 public void Dispose() { Cleanup(); } } public class MessageSender { public void SendMessage(string content) { // 发送消息 WeakReferenceMessenger.Default.Send(new UserMessage(content)); } } }
C#
namespace App10 { internal class Program { static void Main(string[] args) { // 创建接收者 using (var receiver = new MessageReceiver()) { // 创建发送者 var sender = new MessageSender(); // 发送几条测试消息 sender.SendMessage("你好,这是第一条消息!"); sender.SendMessage("这是第二条消息。"); sender.SendMessage("这是最后一条消息。"); } } } }

image.png

高级用法

使用消息标记(Token)

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; namespace App10 { public class TokenExample { // 定义消息标记 private static readonly string ChatRoomToken = "ChatRoom1"; // 定义消息类型 public class UserMessage { public string Content { get; } public DateTime Timestamp { get; } public string SenderName { get; } public UserMessage(string content, string senderName = "Anonymous") { Content = content; Timestamp = DateTime.Now; SenderName = senderName; } } public class Receiver : IDisposable { private bool _isDisposed; public Receiver() { // 使用标记注册消息 WeakReferenceMessenger.Default.Register<UserMessage, string>( this, ChatRoomToken, HandleMessage ); } private void HandleMessage(object recipient, UserMessage message) { Console.WriteLine($"[{message.Timestamp:HH:mm:ss}] {message.SenderName}: {message.Content}"); } public void Dispose() { if (!_isDisposed) { // 取消注册消息,防止内存泄漏 WeakReferenceMessenger.Default.Unregister<UserMessage, string>(this, ChatRoomToken); _isDisposed = true; } } } public class Sender { private readonly string _senderName; public Sender(string senderName) { _senderName = senderName; } public void SendToSpecificChatRoom(string content) { if (string.IsNullOrEmpty(content)) { throw new ArgumentNullException(nameof(content), "消息内容不能为空"); } // 使用标记发送消息 WeakReferenceMessenger.Default.Send(new UserMessage(content, _senderName), ChatRoomToken); } } // 使用示例 public static void Example() { // 创建接收者 using var receiver1 = new Receiver(); using var receiver2 = new Receiver(); // 创建发送者 var sender1 = new Sender("User1"); var sender2 = new Sender("User2"); // 发送消息 sender1.SendToSpecificChatRoom("大家好!"); sender2.SendToSpecificChatRoom("你好啊!"); // 测试空消息 try { sender1.SendToSpecificChatRoom(null); } catch (ArgumentNullException ex) { Console.WriteLine($"错误: {ex.Message}"); } } } }

image.png

使用消息处理器(Handler)

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace App11 { // 定义消息类 public class UserMessage { public string Content { get; } public UserMessage(string content) { Content = content; } } }
C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; namespace App11 { // 消息发送者类 public class MessageSender { public void SendMessage(string content) { // 发送消息 WeakReferenceMessenger.Default.Send(new UserMessage(content)); } } }
C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; namespace App11 { // 消息处理器类 public class MessageHandler : IRecipient<UserMessage>, IDisposable { public MessageHandler() { // 实现 IRecipient 接口的类可以使用这种方式注册 WeakReferenceMessenger.Default.RegisterAll(this); } public void Receive(UserMessage message) { Console.WriteLine($"Handler收到消息: {message.Content}"); } public void Cleanup() { WeakReferenceMessenger.Default.UnregisterAll(this); } // 实现 IDisposable 接口,确保资源正确释放 public void Dispose() { Cleanup(); } } }
C#
namespace App11 { internal class Program { static void Main(string[] args) { // 创建消息处理器 using (var handler = new MessageHandler()) { // 创建消息发送者 var sender = new MessageSender(); // 发送几条测试消息 sender.SendMessage("Hello, World!"); sender.SendMessage("这是第二条消息"); sender.SendMessage("这是最后一条消息"); } Console.ReadLine(); } } }

image.png

使用消息过滤器

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; namespace App11 { public class FilterExample { public class PriorityMessage { public string Content { get; } public int Priority { get; } public PriorityMessage(string content, int priority) { Content = content; Priority = priority; } } public class FilteredReceiver : IRecipient<PriorityMessage> { public FilteredReceiver() { // 注册消息接收 WeakReferenceMessenger.Default.Register<PriorityMessage>(this); } // 实现IRecipient接口的消息处理方法 public void Receive(PriorityMessage message) { if (message.Priority > 5) // 过滤条件 { Console.WriteLine($"收到高优先级消息: {message.Content}"); } } // 清理方法 public void Cleanup() { WeakReferenceMessenger.Default.Unregister<PriorityMessage>(this); } } // 消息发送者 public class MessageSender { public void SendMessages() { // 发送不同优先级的消息 WeakReferenceMessenger.Default.Send(new PriorityMessage("低优先级消息", 3)); WeakReferenceMessenger.Default.Send(new PriorityMessage("高优先级消息1", 7)); WeakReferenceMessenger.Default.Send(new PriorityMessage("低优先级消息", 4)); WeakReferenceMessenger.Default.Send(new PriorityMessage("高优先级消息2", 8)); } } // 演示运行方法 public static void RunExample() { // 创建接收者 var receiver = new FilteredReceiver(); // 创建发送者并发送消息 var sender = new MessageSender(); sender.SendMessages(); // 清理资源 receiver.Cleanup(); } } }

image.png

注意事项

  1. 内存管理
    • WeakReferenceMessenger 使用弱引用,但仍需要注意及时注销不需要的消息订阅
    • 在对象销毁前调用 Unregister 或 UnregisterAll 方法
  2. 性能考虑
    • 避免过于频繁地发送消息
    • 消息内容应该保持简洁
    • 考虑使用消息过滤器减少不必要的消息处理
  3. 调试技巧
    • 使用日志记录消息的发送和接收
    • 在开发环境中实现消息追踪机制

总结

WeakReferenceMessenger 是一个强大的消息传递工具,它可以帮助我们实现松耦合的组件通信。通过合理使用它的各种特性,我们可以构建出可维护、可扩展的应用程序架构。在使用过程中,要注意内存管理和性能优化,同时保持代码的清晰和可维护性。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!