WPF中使用路由模式处理Mqtt消息 直接上代码特征[AttributeUsage(AttributeTargets.Method,AllowMultipletrue,Inheritedfalse)]publicclassMqttTopicAttribute:Attribute{publicstringTopic{get;}/// summary/// 描述可选用于日志/文档/// /summarypublicstringDescription{get;set;};publicMqttTopicAttribute(stringtopic){if(string.IsNullOrWhiteSpace(topic))thrownewArgumentException(Topic 不能为空,nameof(topic));Topictopic;}}注册路由/// summary/// 路由注册/// /summarypublicclassMqttRouteRegistry{publicDictionarystring,List(Type ServiceType,MethodInfo Method)Routes{get;}new(StringComparer.OrdinalIgnoreCase);publicvoidScanAssembly(Assemblyassembly){foreach(vartypeinassembly.GetTypes()){varmethodstype.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);foreach(varmethodinmethods){//使用 GetCustomAttributes 获取方法上贴的所有 MqttTopic 特性varattributesmethod.GetCustomAttributesMqttTopicAttribute();foreach(varattributeinattributes){// 验证方法签名必须包含且仅包含一个 stringvarparametersmethod.GetParameters();// 校验参数类型是否为 MqttMessageContextif(parameters.Length!1||parameters[0].ParameterType!typeof(MqttMessageContext)){thrownewInvalidOperationException($[MqttTopic] 方法{type.Name}.{method.Name}必须有且仅有一个 MqttMessageContext 参数);}// 验证返回值if(method.ReturnType!typeof(Task)method.ReturnType!typeof(void)){thrownewInvalidOperationException($[MqttTopic] 方法{type.Name}.{method.Name}返回值必须是 void 或 Task);}// 初始化或追加到列表if(!Routes.TryGetValue(attribute.Topic,outvarhandlerList)){handlerListnewList(Type,MethodInfo)();Routes[attribute.Topic]handlerList;}handlerList.Add((type,method));}}}}}路由分发publicrecordMqttMessageContext(stringtopic,stringpayload);/// summary/// 路由分发/// /summarypublicclassMqttMessageDispatcher{privatereadonlyMqttRouteRegistry_registry;privatereadonlyIServiceProvider_serviceProvider;publicMqttMessageDispatcher(MqttRouteRegistryregistry,IServiceProviderserviceProvider){_registryregistry;_serviceProviderserviceProvider;}publicasyncTaskDispatchMessageAsync(stringtopic,stringpayload){// 1. 如果没有任何类订阅这个 Topic直接退出if(!_registry.Routes.TryGetValue(topic,outvarhandlers)||handlers.Count0){return;}// 2. 创建一个顶层的作用域或者为每个订阅者创建独立作用域。// 这里推荐采用“一个 Topic 创建一个 Scope”如果追求极致隔离也可以在 foreach 内部单独 Scope。using(varscope_serviceProvider.CreateScope()){vartasksnewListTask();// 3. 遍历所有订阅了该 Topic 的处理器实现一对多广播foreach(varhandlerinhandlers){// 使用 Task.Run 进行并行多线程分发防止订阅者 A 耗时导致订阅者 B 延迟收到消息tasks.Add(Task.Run(async(){try{// 动态向 DI 容器请求实例例如 MainWindowViewModel、AlarmService 等varinstancescope.ServiceProvider.GetService(handler.ServiceType);if(instancenull)return;varcontextnewMqttMessageContext(topic,payload);// 执行方法if(handler.Method.ReturnTypetypeof(Task)){await(Task)handler.Method.Invoke(instance,newobject[]{context});}else{handler.Method.Invoke(instance,newobject[]{context});}}catch(Exceptionex){// 单个订阅者执行崩溃捕获它不影响其他类接收消息System.Diagnostics.Debug.WriteLine($[Dispatcher] 订阅者{handler.ServiceType.Name}处理失败:{ex.Message});}}));}// 等待当前 Topic 的所有订阅者全部处理完毕awaitTask.WhenAll(tasks);}}}依赖注入// 1. 初始化并注册 MQTT 路由注册表,所有消息处理的类必须注入varregistrynewMqttRouteRegistry();// 扫描当前程序集包含所有 ViewModel 和 Serviceregistry.ScanAssembly(Assembly.GetExecutingAssembly());services.AddSingleton(registry);services.AddSingletonMqttMessageDispatcher();//所有包含 [MqttTopic] 特性的类必须注册到容器中services.AddSingletonMainWindowViewModel();调用[MqttTopic(PLC01/DB7000.58.1)] private async Task UpdateMode(MqttMessageContext context) { Console.WriteLine($收到消息{context.payload}); }

相关新闻

最新新闻

机器人电控系统硬件设计:从输入保护到稳压的电路实战指南

机器人电控系统硬件设计:从输入保护到稳压的电路实战指南

1. 项目概述:从零搭建一个“抗造”的机器人电控系统 搞机器人,无论是参加RoboMaster、Robocon这类大赛,还是自己做一台智能小车或机械臂,最让人头疼的往往不是算法写不出来,而是硬件系统“抽风”。程序跑得好好的&…

2026/7/30 16:26:23
AI文本降重工具原理与应用实践

AI文本降重工具原理与应用实践

1. 项目概述:千笔降AI率助手的核心价值最近在内容创作圈子里,有个工具被频繁提及——千笔降AI率助手。作为每天需要处理大量文字内容的从业者,我最初也是抱着试试看的心态接触这个工具,没想到它彻底改变了我处理AI生成内容的工作流…

2026/7/30 16:26:23
3分钟让你的Windows 11飞起来:Win11Debloat一键优化工具完全指南

3分钟让你的Windows 11飞起来:Win11Debloat一键优化工具完全指南

3分钟让你的Windows 11飞起来:Win11Debloat一键优化工具完全指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declut…

2026/7/30 16:26:23
SDR++ 跨平台软件定义无线电终极指南:10分钟快速上手专业无线电接收

SDR++ 跨平台软件定义无线电终极指南:10分钟快速上手专业无线电接收

SDR 跨平台软件定义无线电终极指南:10分钟快速上手专业无线电接收 【免费下载链接】SDRPlusPlus Cross-Platform SDR Software 项目地址: https://gitcode.com/GitHub_Trending/sd/SDRPlusPlus SDR 是一款功能强大的跨平台软件定义无线电应用程序&#xff0c…

2026/7/30 16:26:23
实验复现的核心流程梳理与关键注意事项指引

实验复现的核心流程梳理与关键注意事项指引

研一新生必装 五个让你少走三年弯路的科研神器 刚进实验室的研一新生最容易陷入迷茫。不知道怎么确定研究方向,看不懂海量外文文献,不会设计合理的实验方案,数据处理和绘图一窍不通,写第一篇学术论文更是无从下手。别慌&#xff…

2026/7/30 16:26:23
LLM项目上线前最后一道生死线:社区支持可持续性压力测试(含30天Issue闭环率追踪模板)

LLM项目上线前最后一道生死线:社区支持可持续性压力测试(含30天Issue闭环率追踪模板)

更多请点击: https://intelliparadigm.com 第一章:LLM项目上线前最后一道生死线:社区支持可持续性压力测试(含30天Issue闭环率追踪模板) 当LLM模型完成训练、评估与部署验证后,真正的考验才刚刚开始——能…

2026/7/30 16:21:22

月新闻