大概看了下C#官方提供的IObservable接口以及IObserver接口来实现发布和订阅,写的很标准,很有代表性,做下笔记,以后要是项目需要用到发布订阅再基于自己的需求改:

public class BaggageInfo
{private int flightNo;private string origin;private int location;internal BaggageInfo(int flight, string from, int carousel){this.flightNo = flight;this.origin = from;this.location = carousel;}public int FlightNumber {get { return this.flightNo; }}public string From {get { return this.origin; }}public int Carousel {get { return this.location; }}
}///
/// 发布者
///
public class BaggageHandler : IObservable<BaggageInfo>
{private List<IObserver<BaggageInfo>> observers;private List<BaggageInfo> flights;public BaggageHandler(){observers = new List<IObserver<BaggageInfo>>();flights = new List<BaggageInfo>();}public IDisposable Subscribe(IObserver<BaggageInfo> observer){// Check whether observer is already registered. If not, add itif (! observers.Contains(observer)) {observers.Add(observer);// Provide observer with existing data.foreach (var item in flights)observer.OnNext(item);}return new Unsubscriber<BaggageInfo>(observers, observer);}// Called to indicate all baggage is now unloaded.public void BaggageStatus(int flightNo){BaggageStatus(flightNo, String.Empty, 0);}public void BaggageStatus(int flightNo, string from, int carousel){var info = new BaggageInfo(flightNo, from, carousel);// Carousel is assigned, so add new info object to list.if (carousel > 0 && ! flights.Contains(info)) {flights.Add(info);foreach (var observer in observers)observer.OnNext(info);}else if (carousel == 0) {// Baggage claim for flight is donevar flightsToRemove = new List<BaggageInfo>();foreach (var flight in flights) {if (info.FlightNumber == flight.FlightNumber) {flightsToRemove.Add(flight);foreach (var observer in observers)observer.OnNext(info);}}foreach (var flightToRemove in flightsToRemove)flights.Remove(flightToRemove);flightsToRemove.Clear();}}public void LastBaggageClaimed(){foreach (var observer in observers)observer.OnCompleted();observers.Clear();}
}
internal class Unsubscriber<BaggageInfo> : IDisposable
{private List<IObserver<BaggageInfo>> _observers;private IObserver<BaggageInfo> _observer;internal Unsubscriber(List<IObserver<BaggageInfo>> observers, IObserver<BaggageInfo> observer){this._observers = observers;this._observer = observer;}public void Dispose() {if (_observers.Contains(_observer))_observers.Remove(_observer);}
}///
/// 订阅者
///
public class ArrivalsMonitor : IObserver<BaggageInfo>
{private string name;private List<string> flightInfos = new List<string>();private IDisposable cancellation;private string fmt = "{0,-20} {1,5}  {2, 3}";public ArrivalsMonitor(string name){if (String.IsNullOrEmpty(name))throw new ArgumentNullException("The observer must be assigned a name.");this.name = name;}public virtual void Subscribe(BaggageHandler provider){cancellation = provider.Subscribe(this);}public virtual void Unsubscribe(){cancellation.Dispose();flightInfos.Clear();}public virtual void OnCompleted() {flightInfos.Clear();}// No implementation needed: Method is not called by the BaggageHandler class.public virtual void OnError(Exception e){// No implementation.
   }// Update information.public virtual void OnNext(BaggageInfo info) {bool updated = false;// Flight has unloaded its baggage; remove from the monitor.if (info.Carousel == 0) {var flightsToRemove = new List<string>();string flightNo = String.Format("{0,5}", info.FlightNumber);foreach (var flightInfo in flightInfos) {if (flightInfo.Substring(21, 5).Equals(flightNo)) {flightsToRemove.Add(flightInfo);updated = true;}}foreach (var flightToRemove in flightsToRemove)flightInfos.Remove(flightToRemove);flightsToRemove.Clear();}else {// Add flight if it does not exist in the collection.string flightInfo = String.Format(fmt, info.From, info.FlightNumber, info.Carousel);if (! flightInfos.Contains(flightInfo)) {flightInfos.Add(flightInfo);updated = true;}}if (updated) {flightInfos.Sort();Console.WriteLine("Arrivals information from {0}", this.name);foreach (var flightInfo in flightInfos)Console.WriteLine(flightInfo);Console.WriteLine();}}
}
using System;
using System.Collections.Generic;public class Example
{public static void Main(){//发布者BaggageHandler provider = new BaggageHandler();// 订阅者ArrivalsMonitor observer1 = new ArrivalsMonitor("BaggageClaimMonitor1");// 订阅者ArrivalsMonitor observer2 = new ArrivalsMonitor("SecurityExit");// 发布provider.BaggageStatus(712, "Detroit", 3);//订阅
        observer1.Subscribe(provider);provider.BaggageStatus(712, "Kalamazoo", 3);provider.BaggageStatus(400, "New York-Kennedy", 1);provider.BaggageStatus(712, "Detroit", 3);observer2.Subscribe(provider);provider.BaggageStatus(511, "San Francisco", 2);provider.BaggageStatus(712);observer2.Unsubscribe();provider.BaggageStatus(400);provider.LastBaggageClaimed();}
}

View Code

转载于:https://www.cnblogs.com/zhiyong-ITNote/p/10121600.html

C#订阅与发布标准实现相关推荐

  1. ROS与Arduino学习(三)订阅与发布

    ROS与Arduino学习(三)订阅与发布 Tutorial Level:HelloWorld Next Tutorial:用ROS的Cmake编译程序 本节介绍如何在arduino中发布与订阅消息. ...

  2. Redis源码剖析(五)订阅与发布

    Redis提供了订阅和发布的功能,允许客户端订阅一个或多个频道,当其他客户端向某个频道发送消息时,服务器会将消息转发给所有订阅该频道的客户端 这一点有点像群聊的功能,一个客户端将消息发往群中(向某个频 ...

  3. 【Vue2.0】— 消息订阅与发布pubsub(二十)

    [Vue2.0]- 消息订阅与发布pubsub(二十)

  4. ros先订阅后发布 无法收到消息的解决办法

    现象 今天遇到的问题是: 使用的是Ros1, 在先订阅后发布时, 会导致订阅者无法收到订阅的消息, 除非在发布者发布后重新订阅. 思考 以前使用的是Ros2似乎并不关心订阅和发布的先后顺序,  似乎都 ...

  5. Redis 订阅与发布

    PUBLISH channel msg将信息 message 发送到指定的频道 channelSUBSCRIBE channel [channel ...]订阅频道,可以同时订阅多个频道UNSUBSC ...

  6. ros2订阅esp32发布的电池电压数据-补充

    ros2订阅esp32发布的电池电压数据 电池电压数据能订阅但是不显示,数据QoS不匹配,需要修改. 默认: 需要使用的是外部机器人通过wifi传递的数据,设置: // create publishe ...

  7. tp5和微信小程序联接mqtt订阅及发布

    前文已经在啊里云宝塔中搭建好mqtt服务器,这里就在tp5及小程序中实现订阅及发布 一.tp5实现 1.先上网下载phpMQTT.php文件 https://github.com/bluerhinos ...

  8. Redis订阅与发布原理

    记录下来以后方便回忆,需要时随时翻阅 Redis 订阅与发布 原理 client->pubsub_channels 是客户端维护的一个以dict结构的维护的订阅频道哈希表,VAL是NULL,不需 ...

  9. redis操作订阅和发布

    redis中订阅和发布,可以理解为java设计模式中的生产者和消费者模式,一个生产数据,一个消费数据,消费数据的呢,开启一个阻塞线程,等待生产数据,接下来我们看看redis怎样操作,我们需要开启两个终 ...

最新文章

  1. SpringMVC之源码分析--ViewResolver(四)
  2. DWZ关闭navTab后刷新指定的navTab
  3. eq值 推荐算法_C++实现十种排序算法
  4. python适用的操作系统是什么_学习Python一般使用什么操作系统?
  5. 前端网页制作-javaScripe 初学笔记
  6. python123蟒蛇代码_[蟒蛇菜谱] Python封装shell命令
  7. 微型计算机的字长不一定是字节的整数倍数,2015江苏省全国计算机等级考试二级VB笔试试卷及参考答案考试技巧重点...
  8. consul服务下线通知_服务注册中心如何实现秒级服务上下线通知 | SOFARegistry 解析...
  9. python爬取同花顺_python 同花顺
  10. 智能优化算法:樽海鞘群优化算法-附代码
  11. wincc控件包下载_Simatic HMI WinCC V7.4 SP1 组态软件下载
  12. 数据结构与算法-进阶(十二)最短路径Dijkstra 算法
  13. 微信聊天记录的图片在哪查看
  14. 小情调的伤感空间日志分享:亲爱的、你还不懂么?
  15. 常用的薪酬管理系统有哪些,薪酬管理需要具备哪些功能?
  16. 用php怎么输出一首诗,如何用一首诗总结你的2018年?
  17. 常用iOS的第三方框架
  18. html 磁贴自动布局,也来“玩”Metro UI之磁贴(一)_html/css_WEB-ITnose
  19. arduino继电器控制风扇_Arduino基础入门篇24—继电器控制
  20. 高级驾驶辅助系统ADAS技术介绍

热门文章

  1. 在Ubuntu18.04上安装Nvidia驱动
  2. 用gcc/g++编译运行C/C++程序
  3. PHP问题 —— Notice: Undefined index:
  4. 再谈子网划分方法与子网划分示例
  5. [shell] IT运维之Linux服务器监控方案
  6. 移劢开发者解决方案研究报告——中国开发者生存状况调查
  7. 修改fstab导致linux无法启动的解决
  8. Unity Contrib Project和资料
  9. java 类复制构造方法_java面向对象入门(3)-java构造方法
  10. 排列算法 C++实现