C#怎么实现发布订阅模式 C#如何用事件总线EventBus实现模块间的松耦合消息通信【架构】

C#原生event+delegate可实现发布订阅,需用private字段封装event、判空调用、及时反订阅防泄漏;MediatR适用于需管道中间件的场景,Channel<T>适合后台批量消费,事件总线非万能解耦方案。用 event + delegate 实现最简发布订阅不用引入任何第三方库,C# 原生就能跑通核心逻辑。关键不是"怎么写",而是"谁该负责订阅、谁该触发、委托签名要不要泛型"。常见错误是把 event 声明成 public 字段------这会让外部直接赋值覆盖所有监听器,彻底破坏订阅机制。必须用 private 字段 + public 事件包装器,或直接用自动实现的 event。delegate 类型推荐用 Action<T> 或自定义泛型委托,避免为每种消息类型写一堆非泛型委托触发事件前务必判空:MyEvent?.Invoke(data),否则空引用异常在生产环境很难定位如果发布者生命周期短于订阅者(比如窗体关闭后后台任务还在发消息),记得在释放时调用 -= 反订阅,否则引发内存泄漏public class NewsPublisher{ public event Action<string> NewsPublished; public void Publish(string news) => NewsPublished?.Invoke(news);}用 MediatR 替代手写 EventBus 的真实理由MediatR 不是"更高级的 EventBus",它是把请求/响应、通知、管道中间件这几层职责拆清楚了。如果你只想要"发个消息让别人收到",用它反而绕路;但如果你需要"发完消息后统一加日志、验证、事务包装",它就省掉大量胶水代码。容易踩的坑是混淆 IRequestHandler 和 INotificationHandler:前者是一对一同步处理(如保存订单),后者才是一对多广播(即传统意义上的发布订阅)。注册必须用 AddMediatR(Assembly),漏掉程序集会导致 Handler not found 错误,且无明确提示INotification 默认异步执行,但不会自动 await 所有 handler ------ 如果某个 handler 抛异常,其他 handler 仍会继续执行,这点和原生 event 不同不要在 handler 里直接 new DbContext,MediatR 的 scope 生命周期和 ASP.NET Core 的 request scope 对齐,应通过构造函数注入System.Threading.Channels 适合什么场景下的"发布订阅"当你的"订阅者"其实是消费者线程(比如后台工作队列、批量处理任务),而不是 UI 更新或业务逻辑响应时,Channel<T> 比事件模型更合适。它天然支持背压、限流、取消,且不依赖对象引用关系。 VWO 一个A/B测试工具

相关推荐
TELL52119 分钟前
selenium webdriver 第二次初始化的异常
开发语言·python
Csvn40 分钟前
🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术
后端·python
lilian2331 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
皮卡丘不断更1 小时前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
保卫大狮兄2 小时前
设备管理从台账到报废,完整生命周期一次讲清
数据库·设备管理·设备
数据安全技术观察3 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
大鹏说大话3 小时前
从爬虫到决策引擎:大数据下自媒体如何用Python挖掘用户痛点
开发语言·爬虫·python
Niuguangshuo3 小时前
silero-vad:超轻量级开源 VAD 实践指南
开发语言·python
金銀銅鐵3 小时前
[Java] 一个方法最多可以有多少个入参?
java·jvm
小席是个热心肠3 小时前
Redis的自我学习
数据库·redis·学习