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. IOS - 设置与帮助界面

    设置与帮助 改动头像, 改动password, 移动客服, 帮助, 声明, 关于我们. 代码 // // IndexSetting600ViewController.h // SymptomCheck ...

  2. IOS - UIView停止交互

    UIView停止交互(失去焦点): 设置userInteractionEnabled=NO, 获取交互设置YES. 能够应用于UIButton, UITextField等交互型控件. [editBut ...

  3. LeetCode 929. Unique Email Addresses (独特的电子邮件地址)

    题目标签:String 题目说明 有两个规则针对于 local name. 所以先把local name 和 domain name 分开. 两个规则是: rule 1:'.' 会被去除. (利用re ...

  4. JSP开发学习参考文章

    配置JDK和Tomcat环境变量 http://blog.csdn.net/lijiazhi1987/article/details/2742181 eclipse maven plugin 插件安装 ...

  5. Datatable转换为Json 的方法

    /// <summary>         /// Datatable转换为Json         /// </summary>        /// <param n ...

  6. 65. ExtJs获取文本框中值的几种方式

    转自:https://blog.csdn.net/qiu512300471/article/details/17415675/ 1.Html文本框    如:<input type=" ...

  7. 3.4 目录和spooling

    文件管理部分主要讲文件目录.文件目录它是用于检索文件的.文件目录它是一种文件系统实现按0存取的一种重要手段.一个文件目录它由若干个目录项组成的.每一个目录项它记录了一个文件的相关信息.这个文件信息指明 ...

  8. zookeeper单机安装

    安装zookeeper步骤: 1,下载zookeeper http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/ 2,放到合适目录,解压 ...

  9. [App Store Connect帮助]三、管理 App 和版本(5)添加平台以创建通用购买

    您可以为 App 添加一个平台以创建通用购买.例如,为现有的 iOS App 添加相关的 Apple TVOS App,从而将该 Apple TVOS App 和 iOS App 一同出售. 与创建新 ...

  10. [Swift通天遁地]二、表格表单-(15)自定义表单文本框内容的格式

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