响应式编程
用响应式编程,可以把事件流当做数据流来处理。
黄金法则:如果把任何事件参数传入一个事件,那么摒弃常用的事件处理程序,转而使用System.Reactive,这将给代码带来益处。
System.Reactive曾被称作Reactive Extentions(响应式扩展),长城为Rx.也就是说,System.Reactive、Reactive Extentions和Rx指的都是同一种技术
响应式编程基于可观察流的概念。当订阅一个可观察流时,便会收到任意数量的数据项(OnNext),然后这个流可能会以单个错误(OnError)或者”流结束”通知结束(OnCompleted)。有些可观察流永远不会结束。实现的接口与下面代码类似
interface IObserver<in T>
{
void OnNext(T item);
void OnCompleted();
void OnError(Exception error);
}
interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
千万别嵌入这样的接口。微软公司的System.Reactive库包含了你需要的一切接口。响应式代码的最终形式与LINQ非常类似,可以把它当做LINQ to Events。System.Reactive库具备了LINQ所能实现的一切,另外,它还增加了许多自己的运算符,特别是处理时间的运算符:
Observable.Interval(TimeSpan.FromSeconds(1))
.Timestamp()
.Where(x=>x.Value%2==0)
.Select(x=>x.Timestamp)
.Subscribe(x=>Trace.WriteLine(x),
ex=>Trace.WriteLine(ex));
该示例代码以一个计数器开始,在周期性计时器(Interval)上运行,并且针对每个实践添加时间戳(Timestamp)。然后,这段代码会过滤部分事件,只留下那些偶数计数值的事件(Where),接着选择时间戳的值(Timestamp),当得到每一个时间戳结果值时,将它们写入调试器(Subscribe)。
LINQ to Objects和LINQ to Entities采用的是拉式模型,LINQ查询的枚举会通过查询来拉取数据;LINQ to EVENT(System.Reactive)采用的是推式模型,事件自行传入并经由查询传播。
对热可观察对象和冷可观察对象来说,订阅会有不同的表现。热可观察对象是一种持续运行的事件流,如果在事件传入时没有订阅者,它就会丢失,如鼠标移动。冷可观察对象中并不会始终有事件传入,他会通过启动事件序列来响应订阅。以HTTP下载为例,他就是一种冷可观察对象,订阅会导致发送HTTP请求。
Subscribe运算符应当始终带有错误处理参数。