经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C#订阅与发布标准实现
来源:cnblogs  作者:又见阿郎  时间:2018/12/17 9:51:47  对本文有异议

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

  1. public class BaggageInfo
  2. {
  3. private int flightNo;
  4. private string origin;
  5. private int location;
  6. internal BaggageInfo(int flight, string from, int carousel)
  7. {
  8. this.flightNo = flight;
  9. this.origin = from;
  10. this.location = carousel;
  11. }
  12. public int FlightNumber {
  13. get { return this.flightNo; }
  14. }
  15. public string From {
  16. get { return this.origin; }
  17. }
  18. public int Carousel {
  19. get { return this.location; }
  20. }
  21. }
  22. ///
  23. /// 发布者
  24. ///
  25. public class BaggageHandler : IObservable<BaggageInfo>
  26. {
  27. private List<IObserver<BaggageInfo>> observers;
  28. private List<BaggageInfo> flights;
  29. public BaggageHandler()
  30. {
  31. observers = new List<IObserver<BaggageInfo>>();
  32. flights = new List<BaggageInfo>();
  33. }
  34. public IDisposable Subscribe(IObserver<BaggageInfo> observer)
  35. {
  36. // Check whether observer is already registered. If not, add it
  37. if (! observers.Contains(observer)) {
  38. observers.Add(observer);
  39. // Provide observer with existing data.
  40. foreach (var item in flights)
  41. observer.OnNext(item);
  42. }
  43. return new Unsubscriber<BaggageInfo>(observers, observer);
  44. }
  45. // Called to indicate all baggage is now unloaded.
  46. public void BaggageStatus(int flightNo)
  47. {
  48. BaggageStatus(flightNo, String.Empty, 0);
  49. }
  50. public void BaggageStatus(int flightNo, string from, int carousel)
  51. {
  52. var info = new BaggageInfo(flightNo, from, carousel);
  53. // Carousel is assigned, so add new info object to list.
  54. if (carousel > 0 && ! flights.Contains(info)) {
  55. flights.Add(info);
  56. foreach (var observer in observers)
  57. observer.OnNext(info);
  58. }
  59. else if (carousel == 0) {
  60. // Baggage claim for flight is done
  61. var flightsToRemove = new List<BaggageInfo>();
  62. foreach (var flight in flights) {
  63. if (info.FlightNumber == flight.FlightNumber) {
  64. flightsToRemove.Add(flight);
  65. foreach (var observer in observers)
  66. observer.OnNext(info);
  67. }
  68. }
  69. foreach (var flightToRemove in flightsToRemove)
  70. flights.Remove(flightToRemove);
  71. flightsToRemove.Clear();
  72. }
  73. }
  74. public void LastBaggageClaimed()
  75. {
  76. foreach (var observer in observers)
  77. observer.OnCompleted();
  78. observers.Clear();
  79. }
  80. }
  81. internal class Unsubscriber<BaggageInfo> : IDisposable
  82. {
  83. private List<IObserver<BaggageInfo>> _observers;
  84. private IObserver<BaggageInfo> _observer;
  85. internal Unsubscriber(List<IObserver<BaggageInfo>> observers, IObserver<BaggageInfo> observer)
  86. {
  87. this._observers = observers;
  88. this._observer = observer;
  89. }
  90. public void Dispose()
  91. {
  92. if (_observers.Contains(_observer))
  93. _observers.Remove(_observer);
  94. }
  95. }
  96. ///
  97. /// 订阅者
  98. ///
  99. public class ArrivalsMonitor : IObserver<BaggageInfo>
  100. {
  101. private string name;
  102. private List<string> flightInfos = new List<string>();
  103. private IDisposable cancellation;
  104. private string fmt = "{0,-20} {1,5} {2, 3}";
  105. public ArrivalsMonitor(string name)
  106. {
  107. if (String.IsNullOrEmpty(name))
  108. throw new ArgumentNullException("The observer must be assigned a name.");
  109. this.name = name;
  110. }
  111. public virtual void Subscribe(BaggageHandler provider)
  112. {
  113. cancellation = provider.Subscribe(this);
  114. }
  115. public virtual void Unsubscribe()
  116. {
  117. cancellation.Dispose();
  118. flightInfos.Clear();
  119. }
  120. public virtual void OnCompleted()
  121. {
  122. flightInfos.Clear();
  123. }
  124. // No implementation needed: Method is not called by the BaggageHandler class.
  125. public virtual void OnError(Exception e)
  126. {
  127. // No implementation.
  128. }
  129. // Update information.
  130. public virtual void OnNext(BaggageInfo info)
  131. {
  132. bool updated = false;
  133. // Flight has unloaded its baggage; remove from the monitor.
  134. if (info.Carousel == 0) {
  135. var flightsToRemove = new List<string>();
  136. string flightNo = String.Format("{0,5}", info.FlightNumber);
  137. foreach (var flightInfo in flightInfos) {
  138. if (flightInfo.Substring(21, 5).Equals(flightNo)) {
  139. flightsToRemove.Add(flightInfo);
  140. updated = true;
  141. }
  142. }
  143. foreach (var flightToRemove in flightsToRemove)
  144. flightInfos.Remove(flightToRemove);
  145. flightsToRemove.Clear();
  146. }
  147. else {
  148. // Add flight if it does not exist in the collection.
  149. string flightInfo = String.Format(fmt, info.From, info.FlightNumber, info.Carousel);
  150. if (! flightInfos.Contains(flightInfo)) {
  151. flightInfos.Add(flightInfo);
  152. updated = true;
  153. }
  154. }
  155. if (updated) {
  156. flightInfos.Sort();
  157. Console.WriteLine("Arrivals information from {0}", this.name);
  158. foreach (var flightInfo in flightInfos)
  159. Console.WriteLine(flightInfo);
  160. Console.WriteLine();
  161. }
  162. }
  163. }
  164. using System;
  165. using System.Collections.Generic;
  166. public class Example
  167. {
  168. public static void Main()
  169. {
  170. //发布者
  171. BaggageHandler provider = new BaggageHandler();
  172. // 订阅者
  173. ArrivalsMonitor observer1 = new ArrivalsMonitor("BaggageClaimMonitor1");
  174. // 订阅者
  175. ArrivalsMonitor observer2 = new ArrivalsMonitor("SecurityExit");
  176. // 发布
  177. provider.BaggageStatus(712, "Detroit", 3);
  178. //订阅
  179. observer1.Subscribe(provider);
  180. provider.BaggageStatus(712, "Kalamazoo", 3);
  181. provider.BaggageStatus(400, "New York-Kennedy", 1);
  182. provider.BaggageStatus(712, "Detroit", 3);
  183. observer2.Subscribe(provider);
  184. provider.BaggageStatus(511, "San Francisco", 2);
  185. provider.BaggageStatus(712);
  186. observer2.Unsubscribe();
  187. provider.BaggageStatus(400);
  188. provider.LastBaggageClaimed();
  189. }
  190. }
View Code

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号