ToEventPattern
本方法并不遵循标准的事件模式。在通常情况下订阅一个事件需要处理sender和EventArgs参数。在之前(ToEvent扩展方法)的例子中我们仅仅拿到了值,但如果你希望队列作为一个时间,遵循标准的模式,就需要使用ToEventPattern方法。
ToEventPattern方法接受一个IObservable<EventPattern<TEventArgs>>并将其转换为一个IEventPatternSource<TEventArgs>。这些类型的公共接口相当简单。
如果我们创建一个EventArgs类型,然后使用Select进行一个简单的transform,就可以做出一个符合模式的标准队列。
The EventArgs type:
The transform:
现在我们就有了一个匹配的队列。
现在我们了解了如何回到.NET事件。总结一下,为什么RX比事件来说是一个更好的模型:
- c#中事件有一个奇怪的接口,+=和-=操作不自然的注册回调
- 事件难于构成
- 事件不提供易用的随着时间查询的能力
- 事件是一个常见的内存泄漏的原因
- 事件没有标准的完成信号
- 事件几乎没有为多线程的并发提供帮助。例如,在一个单独的线程上引发事件需要你完成所有的管道工作
- 谨慎选择进入或退出IObservable<T> monad,因为这样做过多将迅速导致你的代码库混乱,同时说明你的设计可能存在缺陷。
Advanced error handling
发生异常,Exceptions本身并没有好坏之分,而raise或catch的方法有好坏之分。有些Exceptions是可以预测的,或者由于草率的代码,例如DivideByZeroException。其他的Exceptions不能被防御代码阻止,例如I/O异常,如FileNotFoundException或TimeoutException。在这种情况下,我们应该logging错误消息,记录错误,或者重试都是潜在的解决方案。
IObserver<T>接口和Subscribe扩展方法提供处理因出错而被终结的队列的能力,但它们最终将队列终止后离开,也不提供可组合的方式来满足不同类型的异常。RX提供了一个方法可以组织错误处理程序,允许我们继续留在monad之内。
Control flow constructs
我们将使用图表来学习如何用各种方法来处理不同的控制流。像普通的.NET代码一样,使用流量控制结构,如try/catch/finally。本章中我们将看到它如何应用到队列。
Catch
就像在SEH (Structured Exception Handling)中的catch,RX让你可以选择swallowing一个exception,把它包在另一个exception中或执行其他逻辑。
可观测物队列可以使用OnError来处理错误,RX提供一个有效的管理OnError消息的方法:Catch扩展方法。Catch允许拦截特定的异常类型,然后继续使用另外一个队列。
下面是Catch的签名:
Swallowing exceptions
使用RX,你可以使用类似SEH的方式catch和swallow exceptions。我们使用Catch扩展方法并提供一个空队列作为参数second的值。
可以用图例来表示swallowed exception
S1代表第一个队列,它以错误(X)结束。
S2是continuation队列,一个空队列。
R是结果队列,它在S1开始的时候开始,当S1被终结时用S2继续。
Output:
Catch-->1
Catch-->2
Catch completed
这个例子将catch和swallow所有类型的exceptions。这有点像SEH:
Catch有一个重载可以指定异常的类型,正如下面的代码将会catch一个TimeoutException:
这个重载的签名如下:
下面的代码catch了一个TimeoutException。我们提供了一个获取异常并返回队列的委托来代替提供第二个队列,这允许你创建自己的continuation操作。在下面的例子中,我们将添加-1到错误队列然后完成它:
Output:
Catch-->1
Catch-->2
Catch-->-1
Catch completed
结果如我们所看到的,-1被输出了出来。
如果队列是被一个无法转换为TimeoutException的Exception所终结,那么错误不但无法被捕获,还将流向订阅者:
Output:
Catch-->1
Catch-->2
Catch failed-->Fail!
如上所见,订阅者接收到了错误信息。
暂无关于此日志的评论。