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. ios8--加载图片

    // // ViewController.m // 06-资源存放问题 #import "ViewController.h" /** 加载图片的方式: 1. imageNamed: ...

  2. IDEA Spark Streaming 操作(文件源)

    import org.apache.spark.SparkConf import org.apache.spark.streaming.{Seconds, StreamingContext} obje ...

  3. Complicated Expressions(表达式转换)

    http://poj.org/problem?id=1400 题意:给出一个表达式可能含有多余的括号,去掉多余的括号,输出它的最简形式. 思路:先将表达式转化成后缀式,因为后缀式不含括号,然后再转化成 ...

  4. [Apple开发者帐户帮助]八、管理档案(1)创建开发配置文件

    您可以在开发人员帐户中创建开发配置文件,以便在Xcode中手动签署应用程序时使用. 在开始之前,您需要一个App ID,一个或多个开发证书以及一个或多个已注册的设备.您可以使用Xcode为您管理的Ap ...

  5. 页面渐进式消失【JS代码】

    // 设定时间,页面慢慢变透明,直到消失 var opacityInterval = setInterval(function () { // 普通时间转为格林威治时间 var targetDate ...

  6. Jquery音频播放插件下载地址(有Html、JS、CSS、音频)

    有详细的html文件.全部JS代码文件.Css样式文件.测试音频资料 音频播放插件下载链接(百度云): http://pan.baidu.com/s/1pKC904F 提取码评论留邮箱发送,谢谢!

  7. Java系列学习(十一)-内部类

    1.内部类 (1)把类定义在另一个类的内部,该类就称为内部类 (2)内部类的访问规则 A:内部类可以直接访问外部类的成员,包括私有 B:外部类要想访问内部类的成员,必须创建对象 (3)内部类的分类 A ...

  8. 【java基础】java中重载与重写的区别

    重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载Overloading是一个类中多态性的一种表现. ( ...

  9. Cannot resolve symbol R

    最近遇到一个奇怪的问题,在Android build 完版本后,将app 删除后,直接出现 Cannot resolve symbol R , Clean. ReBuild 等试过都没效果. 最终解决 ...

  10. LinearLayout中间布局填充出现的问题

    线性布局如何中间填充,会挤掉他下面的布局,所以中间填充使用layout_weight属性.