public interface IPublisher
{
void Publish<T>(T data); void Subscribe<T>(object subscriber, Action<T> pHandler); void Unsubscribe(object subscriber); void Unsubscribe<T>(object subscriber, Action<T> pHandler);
}
public class Publisher : IPublisher
{
public Publisher()
{
} internal List<Handler> _handlers = new List<Handler>(); internal object _locker = new object(); public void Publish<T>(T data = default(T))
{
List<Handler> handlerList; lock (_locker)
{
handlerList = new List<Handler>(_handlers.Count); var handlersToRemove = new List<Handler>(_handlers.Count); foreach (var handler in _handlers)
{
if (!handler.Sender.IsAlive)
{
handlersToRemove.Add(handler);
}
else if (handler.Type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()))
{
handlerList.Add(handler);
}
} foreach (var htr in handlersToRemove)
{
_handlers.Remove(htr);
}
} foreach (var hl in handlerList)
{
((Action<T>)hl.Action)(data);
}
} public void Subscribe<T>(Action<T> pHandler)
{
Subscribe(this, pHandler);
} public void Subscribe<T>(object subscriber, Action<T> pHandler)
{
var item = new Handler
{
Action = pHandler,
Sender = new WeakReference(subscriber),
Type = typeof(T)
}; lock (_locker)
{
_handlers.Add(item);
}
} public void Unsubscribe()
{
Unsubscribe(this);
} public void Unsubscribe(object subscriber)
{
lock (_locker)
{
var query = _handlers.Where(a => !a.Sender.IsAlive ||
a.Sender.Target.Equals(subscriber)); foreach (var h in query.ToList())
{
_handlers.Remove(h);
}
}
} public void Unsubscribe<T>()
{
Unsubscribe<T>(this);
} public void Unsubscribe<T>(Action<T> pHandler)
{
Unsubscribe(this, pHandler);
} public void Unsubscribe<T>(object subscriber, Action<T> pHandler = null)
{
lock (_locker)
{
var query = _handlers.Where(a => !a.Sender.IsAlive ||
a.Sender.Target.Equals(subscriber) && a.Type == typeof(T)); if (pHandler != null)
{
query = query.Where(a => a.Action.Equals(pHandler));
} foreach (var h in query.ToList())
{
_handlers.Remove(h);
}
}
} internal class Handler
{
public Delegate Action { get; set; }
public WeakReference Sender { get; set; }
public Type Type { get; set; }
}
}

Publisher/Subscriber的更多相关文章

  1. Publisher/Subscriber 订阅-发布模式

    Publisher/Subscriber 订阅-发布模式 本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WC ...

  2. Publisher/Subscriber(发布/订阅者)消息模式开发流程

    该模式的作用是发布者和订阅者 可以相互发送消息 发布者和订阅者都充当 生产者和消费者 发布者 package publisher.to.subscriber; import java.awt.font ...

  3. ROS 消息发布器和订阅器Publisher, Subscriber

    博客参考:https://www.2cto.com/kf/201705/639776.html 1.编写发布器节点节点(Node) 是指 ROS 网络中可执行文件.接下来,将会创建一个发布器节点(“t ...

  4. WCF Publisher/Subscriber 订阅-发布模式

    本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WCF中的发布订阅,主要参考书籍<Programming ...

  5. Writing a Simple Publisher and Subscriber

    用c++实现一个publisher/subscriber publisher #include "ros/ros.h" #include "std_msgs/String ...

  6. ROS 进阶学习笔记(13) - Combine Subscriber and Publisher in Python, ROS

    Combine Subscriber and Publisher in Python, ROS This article will describe an example of Combining S ...

  7. Error Fix – Replication subscriber does not exist on the server anymore(删除Replication时报错的解决办法)

    Recently one of my client has faced weird situation related to SQL Server Replication. Their main da ...

  8. Reactor by Example--转

    原文地址:https://www.infoq.com/articles/reactor-by-example Key takeaways Reactor is a reactive streams l ...

  9. 视频直播点播nginx-rtmp开发手册中文版

    2016年8月18日12:42:35 参照官方文档https://github.com/arut/nginx-rtmp-module/wiki/Directives 请注意这个是粗翻译版,仅供参考,不 ...

随机推荐

  1. 用WKWebView 截取整个Html页面

    以前使用UIWebview时,想截取整个页面,可以调整内部scrollView的frame,之后调用 scrollView的layer的 render 方法,很方便. 但是在WKWebView上,行不 ...

  2. 修改linux终端命令行各字体颜色

    这里我用的是 CentOS 7.5,觉得linux终端命令行全部为白色,会经常导致命令与输出内容难以分辨.于是上网找到修改linux终端命令行颜色的方法,发现通过定义PS1环境变量即可实现,下面我以r ...

  3. C#学习-多态

    由于可以继承基类的所有成员,子类就都有了相同的行为,但是有时子类的某些行为需要相互区别,子类需要覆写父类中的方法来实现子类特有的行为. 多态即相同类型的对象调用相同的方法却表现出不同行为的现象. 只有 ...

  4. php memcached-gui工具

    转载: https://github.com/mailopl/memcached-gui/blob/master/memcached.php 适用于在服务端查看memcache内存数据 php代码: ...

  5. .net core2.x - 关于工作单元(UnitOfWork) 模式

    概要:在搭建框架,顺手说下写下,关于unitofwork,可能你理解了,可能你还不理解,可能与不可能不是重点,重点是感兴趣就看看吧. 1.工作单元(unitofowork)是什么(后面简写uow)? ...

  6. idea整合 spring boot jsp mybatis

    spring  boot  开发起来确实要简单许多 ,spring boot  包含了 spring mvc ;内置tomcat   ;启动只需要主方法即可 1.使用idea新建一个spring bo ...

  7. Servlet(五):请求转发和重定向

    请求转发: 问题: 服务器在接收到浏览器的请求后,仅仅使用一个 Servlet进行请求处理,会造成不同的Servlet逻辑代码 冗余,Servlet的职责不明确. 解决: 使用请求转发. 特点: 一次 ...

  8. BigDecimal类型转换

    djjfbr.setMoney(new BigDecimal(djjfbillrecord.getMoney()));

  9. Jboss getshell

     Jboss 的安装需要 JDK 环境 JDK+JBOSS 包  初始环境配置 系统变量名        变量值 PATH                  %JAVA_HOME%\bin:%JAVA ...

  10. 使用控制台对Redis执行增删改查命令

    使用控制台对Redis执行增删改查命令 在上一篇里,我们已经安装了redis.这一篇我们将一起来学习如何使用"控制台"管理Redis 首先肯定是打开一个控制台,在windows系统 ...