C# 基于消息发布订阅模型的示例(下)

一 背景

  在上面的一篇文章中我们介绍了一个完整地基于消息发布和订阅的模型,这篇文章我将介绍一种简单的基于消息的发布和订阅模型,在这个模型中我们将通过构建一个Publisher类来完成对特定的事件和事件订阅进行封装,这个是一个更加轻量级别的方式,使用这个的主要目的是降低类之间彼此的耦合程度,从而方便代码的扩展和访问,最终使代码结构更加合理。

  我们首先来看看具体的Publisher类的构成,后面我们将会对这个类做一个详细的讲解和分析。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Pangea.Common.Utility
{
    /// <summary>
    /// Publisher/Subscriber pattern
    /// This infrastructure works as an instance.
    /// </summary>
    public sealed class Publisher<EventType> where EventType : IComparable
    {
        private static readonly object _locker = new object();
 
        private static readonly Dictionary<EventType, List<Action<object, object, object, object>>> _eventTypeList = new Dictionary<EventType, List<Action<object, object, object, object>>>();
 
        public static void Attach(EventType key, Action<object, object, object, object> act)
        {
            lock (_locker)
            {
                if (!_eventTypeList.ContainsKey(key))
                    _eventTypeList.Add(key, new List<Action<object, object, object, object>>());
                if (!_eventTypeList[key].Contains(act))
                    _eventTypeList[key].Add(act);
            }
        }
 
        public static void Detach(EventType key)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key))
                {
                    _eventTypeList[key].Clear();
                }
            }
        }
 
        public static void Detach(EventType key, Action<object, object, object, object> act)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key) && _eventTypeList[key].Contains(act))
                {
                    _eventTypeList[key].Remove(act);
                }
            }
        }
 
        public static void Notify(EventType key, object p1, object p2, object p3, object p4)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key))
                {
                    foreach (var act in _eventTypeList[key])
                    {
                        act.Invoke(p1, p2, p3, p4);
                    }
                }
            }
        }
 
        public static void Notify(EventType key, object p1, object p2, object p3)
        {
            Notify(key, p1, p2, p3, null);
        }
 
        public static void Notify(EventType key, object p1, object p2)
        {
            Notify(key, p1, p2, null, null);
        }
 
        public static void Notify(EventType key, object p1)
        {
            Notify(key, p1, null, null, null);
        }
 
        public static void Notify(EventType key)
        {
            Notify(key, null, null, null, null);
        }
    }
}

二 完成分析

  在上面的Publisher类中,我们使用了一个EventType类型的泛型参数,这个参数由我们自己来进行定义,一般定义为枚举类型用于标识我们唯一的事件类型,定义好了泛型参数后我们定义了一个_eventTypeList用于定义具体的EventType和对应的处理方法并且将这个放到一个静态的Dictionary中,当然我们在代码中一个事件可以对应多个处理的Action,但是在一般情况下一个事件只有一个对应的处理函数,这里也不排除一个事件对应多个事件的处理函数,另外这里我们默认定义了四个object类型的参数,用于向处理函数进行参数的传递,另外我们的方法都是静态的方法并且在订阅的过程中加了锁从而保证了多线程的环境中保证线程的安全性。

三 使用过程

  在具体的使用过程中主要包括三个重要的步骤:1 定义事件类型。2  消息接收方订阅事件处理(一般在构造函数中调用Attach方法创建时间的唯一订阅)。3  事件发布方发布事件(事件的发送方触发时间并传递参数,调用Notify方式触发事件),完成以上三个步骤就完成了整个基于消息的发布订阅的简单处理,这个Publisher类在处理一般的事件方法中都能够顺利实现,最重要的是事件本身简单易于理解而且能最大程度上降低模块间的耦合,所以在使用的时候还是非常方便的。

以上就是C# 基于消息发布订阅模型的示例(下)的详细内容,更多关于c# 发布订阅模型的资料请关注我们其它相关文章!

(0)

相关推荐

  • 带着问题读CLR via C#(笔记一)CLR的执行模型

    Q1: 什么是CLR? A1: CLR (Common Language Runtime) 是一个可以由多种编程语言使用的"运行时". Q2: CLR的核心功能有哪些? A2: 1)内存管理:2)程序集加载:3)安全性:4)异常处理:5)线程同步 Q3: CLR与使用的编程语言有关吗? A3: 无关.只要编译器是面向CLR的就行. Q4: 选用不同编程语言经过面向CLR的编译器编译后生成的结果相同吗? A4: 相同.无论选择什么语言,相应的编译器变异的结果都是一个托管模块,即一个标准的

  • C# 基于消息发布订阅模型的示例(上)

    在我们的开发过程中,我们经常会遇到这样的场景就是一个对象的其中的一些状态依赖于另外的一个对象的状态,而且这两个对象之间彼此是没有关联的,及两者之间的耦合性非常低,特别是在这种基于容器模型的开发中遇到的会非常多,比如Prism框架或者MEF这种框架中,而我们会发现在这样的系统中我们经常使用一种Publish和Subscribe的模式来进行交互,这种交互有什么好处呢?基于带着这些问题的思考,我们来一步步来剖析! 首先第一步就是定义一个叫做IEventAggregator的接口,里面定义了一些重载的S

  • C# API中模型与它们的接口设计详解

    关键要点 可变模型应该具备自我验证的能力,并实现验证接口. 在共享对象时(特别是在跨线程共享时),考虑使用不可变模型. 考虑支持MVVM风格UI的单层和多层撤消. 在实现属性变更通知时避免不必要的内存分配. 不要覆盖模型的Equals和GetHashCode方法. 在传统的MVC.MVP.MVVM.Web MVC这些UI模式中,模型是一个公共元素.虽然有很多文章讨论这些架构中的视图和控制器,但几乎无一涉及模型.在本文中,我们将讨论模型本身以及相应的.NET接口. 我想先定义一些术语,这些术语在其

  • 支持多类型数据库的c#数据库模型示例

    DataAccess.cs 复制代码 代码如下: using System;using System.Collections.Generic;using System.Text; namespace DynamicFramework{    public abstract class DataAccess : MarshalByRefObject    {        protected System.Data.Common.DbConnection connection;        p

  • C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

    1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用.http协议在应用层运行. 02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证. 03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP.IGMP.RIP.OSPF.IP(v4,v6)等. 04,链路层(Link):又称为物

  • C#获取Visio模型信息的简单方法示例

    前言 Office Visio 是绘制各种类型图表的一个很好的工具,可以绘制业务流程的流程图.网络图.工作流图.数据库模型图.软件图,以及家居设计图等等,可用于可视化和简化业务流程.跟踪项目和资源.绘制组织结构图.映射网络.绘制建筑地图以及优化系统. 在最近的一个项目,要求导出Visio图纸,因为是建筑类的,所以,需要设置墙壁,门,房间等信息的参数. 拿墙壁为例,选中墙壁模型,右键属性,会弹出以下对话框. 需要设置墙长.墙壁厚度等一些列信息. 现在C#操作Visio里例子比较少,所以,花了好久,

  • C# 基于消息发布订阅模型的示例(下)

    一 背景 在上面的一篇文章中我们介绍了一个完整地基于消息发布和订阅的模型,这篇文章我将介绍一种简单的基于消息的发布和订阅模型,在这个模型中我们将通过构建一个Publisher类来完成对特定的事件和事件订阅进行封装,这个是一个更加轻量级别的方式,使用这个的主要目的是降低类之间彼此的耦合程度,从而方便代码的扩展和访问,最终使代码结构更加合理. 我们首先来看看具体的Publisher类的构成,后面我们将会对这个类做一个详细的讲解和分析. using System; using System.Colle

  • springboot基于Redis发布订阅集群下WebSocket的解决方案

    一.背景 单机节点下,WebSocket连接成功后,可以直接发送消息.而多节点下,连接时通过nginx会代理到不同节点. 假设一开始用户连接了node1的socket服务.触发消息发送的条件的时候也通过nginx进行代理,假如代理转到了node2节点上,那么node2节点的socket服务就发送不了消息,因为一开始用户注册的是node1节点.这就导致了消息发送失败. 为了解决这一方案,消息发送时,就需要一个中间件来记录,这样,三个节点都可以获取消息,然后在根据条件进行消息推送. 二.解决方案(s

  • Vue组件之事件总线和消息发布订阅详解

    目录 简介 事件总线 消息的发布订阅 总结 简介 主要介绍事件总线的定义和编写方法和Vue是如何实现消息的订阅与发布的. 事件总线 事件总线是组件间通信的一种方式,适用于任意组件间的通信,比如毫不相干的两个组件.父子组件间.后代组件等等,都能通信. 事件总线有两个特性: 是一个vue组件实例或者一个vue实例,充当一个消息中转站,如果A.B组件想要通信,那么A组件存消息到中转站,B消息拿,或者反过来. 所有组件都要能获取到事件总线. 如果A.B组件间通信,如果A发送数据给B的情况下,需要以下步骤

  • C++基于消息队列的多线程实现示例代码

    前言 实现消息队列的关键因素是考量不同线程访问消息队列的同步问题.本实现涉及到几个知识点 std::lock_guard 介绍 std::lock_gurad 是 C++11 中定义的模板类.定义如下: template <class Mutex> class lock_guard; lock_guard 对象通常用于管理某个锁(Lock)对象,因此与 Mutex RAII 相关,方便线程对互斥量上锁,即在某个 lock_guard 对象的声明周期内,它所管理的锁对象会一直保持上锁状态:而 l

  • SpringBoot整合Redis实现消息发布与订阅的示例代码

    当我们在多个集群应用中使用到本地缓存时,在数据库数据得到更新后,为保持各个副本当前被修改的数据与数据库数据保持同步,在数据被操作后向其他集群应用发出被更新数据的通知,使其删除;下次当其他应用请求该被更新的数据时,应用会到数据库去取,也就是最新的数据,从而使得被更新数据与数据库保持同步! 能实现发送与接收信息的中间介有很多,比如:RocketMQ.RabbitMQ.ActiveMQ.Kafka等,本次主要简单介绍Redis的推送与订阅功能并集成Spring Boot的实现. 1.添加SpringB

  • kafka 消息队列中点对点与发布订阅的区别说明

    目录 背景知识 1.JMS中定义 2.二者分析与区别 2.1 点对点模式 2.2 发布订阅模式 3.流行的消息队列模型比较 3.1 RabbitMQ 3.2 Kafka 背景知识 JMS一个在 Java标准化组织(JCP)内开发的标准(代号JSR 914).2001年6月25日,Java消息服务发布JMS 1.0.2b,2002年3月18日Java消息服务发布 1.1. Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM

  • Redis实现消息的发布订阅原理分析

    目录 一.什么是发布和订阅 二.Redis的发布和订阅 三.redis 发布订阅常用命令 四.命令实战 1.基本使用 2.订阅符合要求的频道 3.查看活跃频道 五.发布订阅原理 1.订阅频道原理 2.发布信息原理 3.退订信息原理 一.什么是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息. 特点:Redis 客户端可以订阅任意数量的频道. 这就好比粉丝们关注了我,当我写完文章发布的时候,你们打开CSDN也会接收

  • ASP.NET Core实现单体程序的事件发布/订阅详解

    背景 事件发布/订阅是一种非常强大的模式,它可以帮助业务组件间实现完全解耦,不同的业务组件只依赖事件,只关注哪些事件是需要自己处理的,而不用关注谁来处理自己发布事件,事件追溯(Event Sourcing)也是基于事件发布/订阅的.在微服务架构中,事件发布/订阅有非常多的应用场景.今天我给大家分享一个基于ASP.NET Core的单体程序使用事件发布/订阅的例子,针对分布式项目的事件发布/订阅比较复杂,难点是事务处理,后续我会另写一篇博文来演示. 案例说明 当前我们有一个基于ASP.NET Co

  • springboot整合netty-mqtt-client实现Mqtt消息的订阅和发布示例

    目录 1.添加依赖 2.源码 3.运行测试 1.添加依赖 <dependency> <groupId>org.jetlinks</groupId> <artifactId>netty-mqtt-client</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>junit</groupId

随机推荐