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. Linux /etc/sudoers 文件详解

    [root@test ~]# cat /etc/sudoers## Sudoers allows particular users to run various commands as## the r ...

  2. python实现简单的登录管理

    import json,timeusername=[]userpasswd=[]def login_success_file(name): try: f=open(r"F:/login_su ...

  3. Intellij Idea 2016创建web项目

    一.创建简单web项目 1.创建一个web project File -> new Project ->选择project sdk 为1.8(已经配过环境变量)其他不要选 -> Ne ...

  4. 一起学HBase——总结HBase中的PUT、GET、DELETE操作

    传统的关系型数据库有CRUD增删改查操作,同样对于NoSQL列式数据库也有CRUD操作.本文对HBase中常用的Scan.GET.PUT.DELETE操作的用法做个总结. Put操作 Put相当于传统 ...

  5. ASP.NET Core 3.0预览版体验

    目前.NET Core 3.0的版本为.NET Core 3.0 Preview 3,对应ASP.NET Core 3.0 Preview 3. ASP.NET Core 3.0 之后将不再支持.NE ...

  6. 读取InputStream 中的内容

      读取InputStream 中的内容 ]) { , len); //把读取到的内容写到输出流中 } //<4> 把字节数组转换为字符串 String content = baos.to ...

  7. [Mongo]Linux上启动与关闭MongoDB

    文档地址:https://docs.mongodb.com/v3.0/tutorial/install-mongodb-on-amazon/ 默认配置下,Mongo实例会将其数据文件存放在/var/l ...

  8. YII2 用 in查询的时候出现无结果, 删除某些值后查询有结果 提前sort数组即可

    YII2 用 in查询的时候出现无结果, 删除某些值后查询有结果, 在数组前用了一个 array_merge 合并了2个数组. 排查发现是 数组中键值没有挨着从0开始 另外没有从小到大, 没观察室哪个 ...

  9. Android应用程序类型和进程状态

    来自<Android4高级编程> Android应用程序不能控制自己的生命周期,应用程序组件(Activity.Service等其他组件)必须监听应用程序状态的变化并做出适当的反应,而且特 ...

  10. word使用新技能

    office2013版,菜单栏-审阅-修订-所有标记,可以显示编辑过程中的所有修改步骤,还可查看未修改的原始状态.前提是“修订”按钮 要点亮! 给文档添加索引,并自动生成索引列表 文件-选项-显示-隐 ...