class Program
{
public static void Main()
{
// Define a provider and two observers.
LocationTracker provider = new LocationTracker();
LocationReporter reporter1 = new LocationReporter("FixedGPS");
reporter1.Subscribe(provider);
LocationReporter reporter2 = new LocationReporter("MobileGPS");
reporter2.Subscribe(provider); provider.TrackLocation(new Location(47.6456, -122.1312));
reporter1.Unsubscribe();
provider.TrackLocation(new Location(47.6677, -122.1199));
provider.TrackLocation(null);
provider.EndTransmission(); Console.ReadLine(); // The example displays output similar to the following:
// FixedGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6677, -122.1199
// MobileGPS: The location cannot be determined.
// The Location Tracker has completed transmitting data to MobileGPS.
}
}
public struct Location
{
double lat, lon; public Location(double latitude, double longitude)
{
this.lat = latitude;
this.lon = longitude;
} public double Latitude
{ get { return this.lat; } } public double Longitude
{ get { return this.lon; } }
}
public class LocationReporter : IObserver<Location>
{
private IDisposable unsubscriber;
private string instName; public LocationReporter(string name)
{
this.instName = name;
} public string Name
{ get { return this.instName; } } public virtual void Subscribe(IObservable<Location> provider)
{
if (provider != null)
unsubscriber = provider.Subscribe(this);
} public virtual void OnCompleted()
{
Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", this.Name);
this.Unsubscribe();
} public virtual void OnError(Exception e)
{
Console.WriteLine("{0}: The location cannot be determined.", this.Name);
} public virtual void OnNext(Location value)
{
Console.WriteLine("{2}: The current location is {0}, {1}", value.Latitude, value.Longitude, this.Name);
} public virtual void Unsubscribe()
{
unsubscriber.Dispose();
}
}
public class LocationTracker : IObservable<Location>
{
public LocationTracker()
{
observers = new List<IObserver<Location>>();
} private List<IObserver<Location>> observers; public IDisposable Subscribe(IObserver<Location> observer)
{
if (!observers.Contains(observer))
observers.Add(observer);
return new Unsubscriber(observers, observer);
} private class Unsubscriber : IDisposable
{
private List<IObserver<Location>> _observers;
private IObserver<Location> _observer; public Unsubscriber(List<IObserver<Location>> observers, IObserver<Location> observer)
{
this._observers = observers;
this._observer = observer;
} public void Dispose()
{
if (_observer != null && _observers.Contains(_observer))
_observers.Remove(_observer);
}
} public void TrackLocation(Nullable<Location> loc)
{
foreach (var observer in observers)
{
if (!loc.HasValue)
observer.OnError(new LocationUnknownException());
else
observer.OnNext(loc.Value);
}
} public void EndTransmission()
{
foreach (var observer in observers.ToArray())
if (observers.Contains(observer))
observer.OnCompleted(); observers.Clear();
}
}
public class LocationUnknownException : Exception
{
internal LocationUnknownException()
{ }
}

C# 通知机制 IObserver<T> 和 IObservable<T>的更多相关文章

  1. 二 Java利用等待/通知机制实现一个线程池

    接着上一篇博客的 一Java线程的等待/通知模型 ,没有看过的建议先看一下.下面我们用等待通知机制来实现一个线程池 线程的任务就以打印一行文本来模拟耗时的任务.主要代码如下: 1  定义一个任务的接口 ...

  2. inotify--内核中文件系统的通知机制

    转载:http://www.ibm.com/developerworks/cn/linux/l-inotifynew/index.html 一. 引言 众所周知,Linux 桌面系统与 MAC 或 W ...

  3. spring事件通知机制详解

    优势 解耦 对同一种事件有多种处理方式 不干扰主线(main line) 起源 要讲spring的事件通知机制,就要先了解一下spring中的这些接口和抽象类: ApplicationEventPub ...

  4. 浅析SQL Server 2005中的主动式通知机制

    一.引言 在开发多人同时访问的Web应用程序(其实不只这类程序)时,开发人员往往会在缓存策略的设计上狠下功夫.这是因为,如果将这种环境下不常变更的数据临时存放在应用程序服务器或是用户机器上的话,可以避 ...

  5. 《深入浅出WPF》重点摘要(—)Binding自动通知机制

    最近因为公司的项目需要用WPF开发,就学习了一下WPF.刚开始只是用到什么就百度什么,虽然功能是实现了,但还是没有弄清楚原理(如果不弄清原理,会感觉很心虚,整个人会没底气),所以决定找个教程系统地学一 ...

  6. HTML 5的消息通知机制

    译文来源:http://www.ido321.com/1130.html 原文:HTML 5 Notification 译文:HTML 5 的消息通知机制 译者:dwqs HTML 5 已经被应用到W ...

  7. Java Concurrency - wait & notify, 等待通知机制

    生产者消费者问题是一个常见的多线程同步案例:一组生产者线程和一组消费者线程共享一个初始状态为空.大小为 N 的缓冲区.只有当缓冲区没满的时候,生产者才能把消息放入缓冲区,否则必须等待:只有缓冲区不空的 ...

  8. Cocos中的观察者设计模式与通知机制

    观察者(Observer)模式也叫发布/订阅(Publish/Subscribe)模式,是 MVC( 模型-视图-控制器)模式的重要组成部分.天气一直是英国人喜欢讨论的话题,而最近几年天气的变化也成为 ...

  9. Android应用程序组件Content Provider的共享数据更新通知机制分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6985171 在Android系统中,应用程序组 ...

随机推荐

  1. TensorFlow 官方文档中文版

    http://wiki.jikexueyuan.com/list/deep-learning/ TensorFlow 官方文档中文版 你正在阅读的项目可能会比 Android 系统更加深远地影响着世界 ...

  2. 命令行下mysql的部分操作

    远程链接数据库: mysql –u用户名 [–h主机名或者IP地址] –p密码 (用户名是登录的用 户,主机名或者IP地址为可选项,如果是本地连接则不需要,远程连接需要填写,密码是对应用户的密码.) ...

  3. AngularJS2.0 hello world例子——引入这么多额外的依赖库真是很忧伤啊

    初识Angular2 写一个Angular2的Hello World应用相当简单,分三步走: 1. 引入Angular2预定义类型 import {Component,View,bootstrap} ...

  4. 自然常数 e 的理解与应用

    某彩票中奖率是百万分之一,则一个人买一百万张彩票仍不中奖的概率是: (1−1106)106≈1e e 往往出现在: 许多微小事件带来的总体变化 随机性和无穷多:

  5. MyBatis高级查询 一对一映射

    drop database if exists simple; create database simple; use simple; drop table if exists sys_user; c ...

  6. js判断ie6的代码

    var isIE=!!window.ActiveXObject; var isIE6=isIE&&!window.XMLHttpRequest; var isIE8=isIE& ...

  7. Behavior Designer扩展

    BehaviorManager.instance.Tick(behaviorTree); 卸载update里u3d直接卡死 = = SharedVariable直接赋值会改变他的引用关系,必须用XXX ...

  8. [Swift通天遁地]八、媒体与动画-(7)实现多个动画的顺序播放效果

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. Xampp mysql无法启动的解决方案

    如果出现mysql 无法启动表明在安装xampp 前已经安装了mysql,造成mysql服务无法启动. 19:06:33  [mysql] MySQL Service detected with wr ...

  10. Prime Ring Problem -- 第一个真正意义上的 搜索

    这个搜索............搜的我头都大了.......不过还是 懂了那么一点点...哈哈 从3/7晚上  做到3/8晚上------从女生到妇女  我都用来做着一道题了......... 所谓的 ...