浏览
月度归档: 2020年12月

[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的操作符。 ···  阅读全文