浏览
分类: Rx.NET

[Rx.NET] 附录 – Rx中的Disposable库

[Rx.NET] 附录 – Rx中的Disposable库

System.Reactive.Core包中包括一个也许有用的附加功能:Rx Disposables库。它是实现了IDisposable接口,并为代码复用提供了通用实现,可以帮助完成大部分释放工作的一组类型。本附录中列出的所有类型都位于System.Reactive.Disposables命名空间中。

下表列出了Disposable及其用途:

类型/效用 描述
Disposable.Create 用于创建Disposable对象的静态方法,当Dispose时执行给定代码
Disposable.Empty 创建一个空的Disposable
ContextDisposable 在给定的SynchronizationContext上运行Dispose的调用
ScheduledDisposable 在给定的IScheduler上运行Dispose的调用
SerialDisposable 内部有一个可替换的Disposable,并且在替换后Dispose前一个Disposable
MultipleAssignmentDisposable 内部有一个可替换的Disposable,并且在替换后不Dispose前一个Disposable
RefCountDisposable 当被引用的所有DisposableDispose后,Dispose内部的Disposable
CompositeDisposable 将多个Disposabel合并为一个可以同时DisposeDisposable
CancellationDisposable Dispose时取消给定的CancellationTokenSource
BooleanDisposable Dispose时设置布尔标志。可以使用IsDisposed属性查看BooleanDisposable是否已经Dispose

Disposable.Create

创建Disposabel最灵活的方式是使用Disposable.Create静态工厂方法。唯一需要做的就是传递一个在调用Dispose时希望执行的操作。下面的示例中,创建了一个可以改变屏幕状态(从忙到不忙)的Disposable。屏幕上显示下载后的新闻信息。当屏幕处于繁忙状态时,UI可以显示一个进度条,向用户展示后台正在进行某些操作。 ···  阅读全文

[Rx.NET] 10 – 错误处理和恢复

[Rx.NET] 10 – 错误处理和恢复

发生错误;是编程生活的日常。为了向程序的用户提供高质量的服务,必须确保代码能够处理错误,并在发生错误时能够正常恢复。否则,用户会遇到程序崩溃或错误行为(例如,错误的计算或意外的警告),这些错误最终可能会导致用户放弃产品。如果发生错误,可能需要忽略并继续,或者为特定的错误添加特定的处理。如果Observable定期从中央服务器推送更新,并且其中一个更新引发了意外错误(例如,网络断开连接),那么通过重新订阅以获取下一组更新来处理错误可能是最好的解决方案。本章将介绍那些用来保护Observable管道的各种错误处理操作符。

除了处理错误外,还可以提前预防某些错误,例如可能导致内存泄漏的不正确的资源处理以及未关闭的服务器连接。以比Observer可以处理的速率更高的速率推送叫做背压,这会导致错误和消耗大量资源。本章将介绍如何正确控制资源的生命周期,即使出现意外错误,也能处理背压问题。

应对错误

在.NET的世界,错误就是一个异常,并且很多原因都能够引发异常。有些(例如,OutOfMemoryException)甚至不受控制。区分Observable管道内可能引发异常的不同位置(或阶段)非常重要,因为对于不同位置,需要不同的方式来处理。 ···  阅读全文

[Rx.NET] 9 – Rx中的并发与同步

[Rx.NET] 9 – Rx中的并发与同步

时间就是一切,至少有人这么说。不像集合(Enumerables),时间在Observable中起到很大作用。通知之间的间隔有大有小,这可能影响处理通知的方式。在上一章,已经介绍了缓存元素和创建随时间推移的滑动窗口的示例。还有执行发生在哪里的问题(例如,线程、任务、调度等等)。时间和执行上下文的概念是有关系的,并且为Rx的并发模型提供了基础。调度类型及其派生表达次模型。本章介绍Rx的调度层,以及如何使用它控制Rx的可观察管道,以及如何使用它和Rx的时间操作符一起使用。

用调度控制并发

在计算机科学中,并发是那些同时执行多个计算并可能相互交互的系统的属性。在前面的章节中谈到了并发,其中提到了不同的.NET异步类型。到目前为止,一直避免谈及Observable管道内如何处理并发。如果使用Interval操作符创建一个每10秒推送一次的Observable,那么在哪个线程中接收通知呢?Observer的订阅在哪个线程中进行?有时,例如使用UI框架时,控制这些执行上下文就很重要,因为对在哪个线程执行操作有限制。通常UI控件只能在UI线程中更改,否则就会引发异常。

Rx遵循此设计准则:引入并发的所有操作都必须使用Scheduler类型,该类型是Rx使用并发和时间的抽象层。 ···  阅读全文

[Rx.NET] 8 – Observable 的分割和组合

[Rx.NET] 8 – Observable 的分割和组合

典型的应用程序通常由多个工作流程组成。 很多情况下,应用程序需要处理多个数据源并对其进行响应,例如UI事件、推送通知、远程过程调用等等。 假设你的应用程序需要使用来自各种来源(例如社交网络)的消息,并以相同的方式对所有消息做出反应。 或者说,你的应用程序处理的是发出各种通知(例如股票价格)流的源,它需要分别(独立)查看通知的每个子组(针对每种股票)。 你需要怎么实现呢?

有多种方式组合Observable并对它们发出的通知做出反应(例如,获取最新,配对或联接)。 并且,有多种方法可根据Observable(例如,按时间或条件)创建子组。 本章将通过使用Enumerables中已经了解的概念并将其应用于Observables世界,将你带入一个新的水平。

组合Observables

虽然使用单个可观察对象很好用; 但是,互联网是由多个独立发生的事件组成的。 为了对从多个Observable发出的通知做出反应,Rx提供了可轻松组合Observable的操作符。 ···  阅读全文

[Rx.NET] 7 – 使用基础查询操作符

[Rx.NET] 7 – 使用基础查询操作符

Observable 推送通知后,Observer 收到通知前通知通常会通过一个管道。本系列的大多数例子都展示了如何使用操作符来操纵控制生成的通知序列,然后最终由 Observer 接收到这些通知。本节将分类解释经常使用到的基础操作符。包括转换和映射,过滤和平展,求和、求平均的聚合运算,以及其他可量化结果的操作。如下图所示:

一些操作符在前面的章节已经介绍过了,但是还没有了解它们的定义及提供的功能。 ···  阅读全文

[Rx.NET] 6 – 控制 Observable 的“温度”

[Rx.NET] 6 – 控制 Observable 的“温度”

Observable 的抽象概念隐藏了 Observer 对通知来源以及推送的了解。根据 Observable 的同实现,Observer 可以共享通知(同一个对象),也可以获取不同的通知实例。Observable 的实现也可以让 Observer 获取整个通知序列,也可以根据订阅时间来获取部分通知。

假设 Observable 推送音乐,作为一个 Observer 并不知道音乐来自现场演奏还是来自留声机。当来自现场时,所有听众(Observer)都共享同一个声音,但是如果来自留声机,声音就是独享的,而且无论何时订阅都可以听完整首音乐。

Observable 温度的概念是指订阅时 Observable 的状态。该状态描述了 Observable 开始及结束推送的事件和通知是否在 Observer 间共享。“热” Observable 是一个活跃的状态,就像现场表演的歌手和推送鼠标当前位置的 Observable。相比之下,“冷” Observable 是一个被动的状态,例如等待播放的专辑和被订阅时在循环中推送数据的 Observable。 ···  阅读全文

[Rx.NET] 5 – 控制 Observer 与 Observable 之间的关系

[Rx.NET] 5 – 控制 Observer 与 Observable 之间的关系

假设你是一位拥有美妙声音,完美歌词,最佳表演的歌手,如果没有粉丝听众当然赚不到钱。对于 Observable 来说是一样的:如果没有 Observer 订阅的话,Observable 就什么也不做,仅仅呆在那里浪费资源。歌手和听众之间的关系何时开始何时结束也是值得研究的,尤其是当播放的是音乐专辑,听众可以跳过或结束播放时。

本篇介绍用于创建 Observer 的方法 和 Observer 必须要实现的重要操作。Observer 与 Observable 之间的订阅关系需要你来维护,你可以控制它何时开始,可以通过通知数量或时间长度控制持续时间,或者两者结合,或者其他一些复杂的逻辑。所有这些都会在本篇介绍一系列操作符时讲到。

创建 Observer

Observer 是 Observable 通知的消费者。可能有很多 Observer 订阅到一个 Observable,也可能是一个 Observer 订阅到很多个 Observable。如下图所示: ···  阅读全文

[Rx.NET] 4 – 从异步类型创建 Observable

[Rx.NET] 4 – 从异步类型创建 Observable

相信大多数人都不喜欢排队,特别是排长队,总感觉这是在浪费时间,我们完全可以做些其他事情(例如读书)。我比较喜欢那些留下排队号然后可以去做些其他事情(例如购物)的餐馆,当有位置可用或快轮到你的时候能通过短信或蜂鸣器通知你,这种服务就很人性化。

同样,我们的代码有时也会排队来等待某些事情,即我们常叫的同步方式;同样,我们的代码也可以在任务完成并能获取结果时被通知,即我们通常叫的异步方式。编写异步代码对程序的响应(并及时做出反应)至关重要,这也是响应的关键特征。本篇将介绍 .NET 的异步执行模式及其与 Observable 的关系,还会介绍从异步类型创建 Observable 的方法及执行此操作可能遇到的问题。

使用 Rx 桥接 .NET 异步类型

Rx 可以很好的处理异步类型。Observable 和 Observer 接口允许生产者(Observable)以同步或异步的形式运行在任何地方,而消费者(Observer)可以接收和处理它的消息通知。这样做有利于测试和更加灵活,因为可以轻松创建一个虚拟的 Observable 来模拟应用场景,并且很容易在生产者方做出调整而不影响消费者。这种关系如下图所示: ···  阅读全文

[Rx.NET] 3 – 创建 Observable

[Rx.NET] 3 – 创建 Observable

当开始学习使用一个东西的时候,通常都会有“从哪里开始学起”的疑问。学习使用 Rx 的答案很简单:从创建 Observable 开始学起。

本篇接下来将介绍多种创建 Observable 的方法。由于篇幅限制本篇只介绍创建同步的 Observable,下一篇介绍创建异步的 Observable。

由于有不同类型的数据源,所以会存在多种创建 Observable 的方式。例如,可以用现存的 .NET 经典事件代码或集合来创建 Observable,并且可以轻松与其他 Observable 组合使用。不同的方式适用于不同的场景,并且具有不同的含义。 ···  阅读全文