Publisher/Subscriber
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的更多相关文章
- Publisher/Subscriber 订阅-发布模式
Publisher/Subscriber 订阅-发布模式 本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WC ...
- Publisher/Subscriber(发布/订阅者)消息模式开发流程
该模式的作用是发布者和订阅者 可以相互发送消息 发布者和订阅者都充当 生产者和消费者 发布者 package publisher.to.subscriber; import java.awt.font ...
- ROS 消息发布器和订阅器Publisher, Subscriber
博客参考:https://www.2cto.com/kf/201705/639776.html 1.编写发布器节点节点(Node) 是指 ROS 网络中可执行文件.接下来,将会创建一个发布器节点(“t ...
- WCF Publisher/Subscriber 订阅-发布模式
本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WCF中的发布订阅,主要参考书籍<Programming ...
- Writing a Simple Publisher and Subscriber
用c++实现一个publisher/subscriber publisher #include "ros/ros.h" #include "std_msgs/String ...
- 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 ...
- 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 ...
- Reactor by Example--转
原文地址:https://www.infoq.com/articles/reactor-by-example Key takeaways Reactor is a reactive streams l ...
- 视频直播点播nginx-rtmp开发手册中文版
2016年8月18日12:42:35 参照官方文档https://github.com/arut/nginx-rtmp-module/wiki/Directives 请注意这个是粗翻译版,仅供参考,不 ...
随机推荐
- JS函数可以再添加属性(包括方法)
1 前言 JS函数可以再添加属性(包括方法),这个有点有趣,记录一下. 2 代码 <!DOCTYPE html> <html> <head> <title&g ...
- 12、Grafan 4.3升级到Grafana 5.0
Upgrading Grafana 升级Grafana We recommend everyone to upgrade Grafana often to stay up to date with t ...
- 阿里云服务器Ubuntu 14.04.2和centos7.5实现nfs挂载
前提条件,确保两个ip可以正常通信 确认服务端是否安装nfs-utils和rpcbind[root@localhost /]# rpm -qa|grep "nfs"nfs4-acl ...
- postgre dinstinct on()的使用
意思是DISTINCT ON ( expression [, …] )把记录根据[, …]的值进行分组,分组之后仅返回每一组的第一行. 需要注意的是,如果你不指定ORDER BY子句,返回的第一条的不 ...
- CAS tomcat6搭建
#genkey:在tomcat根目录下keytool -genkey -alias tomcat_cas -keyalg RSA -storepass changeit -keystore serve ...
- python实现简单的购物车
import json,timeuserinfo={"lanfei": { "passwd":"lanfei", "salary& ...
- Linux 包管理
1 文集 <Linux 包管理基础:apt.yum.dnf 和 pkg>,由Snapcrafter翻译,英文原创(作者Brennen)地址在这里. 这是一篇不错的概括性的文章,系统介绍了D ...
- skywalking6.0.0安装配置(windows),以mysql作为储存。
下载skywalking6.0.0http://skywalking.apache.org/downloads/ 下载jdk8https://www.oracle.com/technetwork/ja ...
- fastadmin表单验证
Unexpected token < in JSON at position 0 注意: if (!form.is("form"))//form的选择器不是form直接返回所 ...
- 设计模式之架构型MVC,MVP,MVVM模式
一.MVCMVC,Model View Controller,是软件架构中最常见的一种设计模式,简单来说就是通过Controller的控制去操作Model层的数据,并且返回给view层展示.View跟 ...