Rx的真实世界示例

可能重复:
react native扩展使用的好例子

我一直在玩Reactive Extension一段时间,但主要限于处理/编写WPF前端内的用户驱动事件。

它是一种非常强大,新的异步编程方式,我很好奇其他人正在做什么,你认为它可以改善我们目前做事的方式?

我们已经在两个项目(Silverlight UI)上使用了RX取得了巨大的成功。 最初的目的是简化WCF访问层 。理性的是,在更糟糕的情况下,我们总是可以恢复到标准(回调)方式,而不会影响更高级别的UI。

我们几乎不知道RX就像一种令人上瘾的药物 – 一旦你开始使用它,就不会再回来了。 像病毒一样,它很快从这个低级通信层一直传播到UI组件:

  • 我们从简单的语法糖开始,使访问WCF服务更简单。
  • 从那里将RX扩展到服务器到客户端异步消息传递是一个自然的步骤
  • 之后使用RX将这两种方式合并为客户端与服务器进行通信,因此viewmodels对于如何接收消息是不可知的默认选项。

然后是完全投降:

  • 需要处理无序的消息?
  • 价格变化时需要在电网上闪一个单元吗?
  • 有一个性能问题,因为客户端被来自服务器的消息轰炸?
  • 有一些基本的CEP逻辑来处理?

好吧,猜猜看,那里有RX运算符;)(如果没有 – 你可以很容易地写一个)

其中最难的部分就是克服我的团队中每个人在开始时都经历过的“我的大脑疼痛 – 如此糟糕”的感觉。 通过多年的处理 – 我的事件 – 通过这种回调编码来限制一个凡人的大脑,就像RX看世界一样。 结果RX代码(特别是一旦它逐渐变得越来越密集,同时处理越来越复杂的场景)对于一个毫无准备的头脑看起来像完整的abracadabra,有趣的确导致一只兔子从一个看似空洞的帽子中拉出来。 不幸的是,现实是在生产代码中没有魔法的地方,因此整个团队必须在船上,这意味着每个人都必须经历这个痛苦的过程,在最初看似非常不自然的方式重新布线。

我会说这是一个人为因素而不是RX API本身,这是有效采用RX的最大障碍。 但男孩是值得的!

我已经编写了一个更完整的库来集成WPF / Silverlight和Rx,文档是(编辑:不再糟糕!),但你可以在以下位置查看:

http://www.reactiveui.net

我用RX来实现以块的forms加载数据(比如sql server management studio)。 使用Reactive Extensions从数据库流式传输数据

Samuel McAravey 在Channel9上播放了一段video,描述了他使用RX构建的真实SilverLight应用程序。 他甚至在CodePlex上提供了它 。

此外,即使您没有异步要求,也可以应用RX时的一些实际用途:

  • 如果您希望允许用户滚动显示侧面某些详细信息的列表,则同步查询详细信息可能会损害您的滚动性能。 .Throttle()是你的朋友。
  • 有时您需要在用户停止输入后立即执行查找。 同样的事情,使用.Throttle,你很好。
  • 在MVVM中使用路由命令 。 非常适合在列表项上使用,只需指定CommandParameter =“{Binding}”,您就可以在容器级别上捕获这些内容。

我们在Silverlight应用程序中从后端加载数据时成功使用Rx。 我们最近从服务器上的SOAP服务纯XML生成迁移,Rx及时出现,以便我们可以使用它代替WebClient或WebRequest(实际上我们现在将WebClient包装在Observable中,但可能会转移到WebRequest)。

几天前我们有一个错误; 我们意识到请求URL太长,以至于它们被截断了。 幸运的是,我们可以将请求拆分为多个并连接响应,但仅使用WebClient解决这个问题意味着创建一个队列和一个状态机来按顺序处理请求…相反,使用Rx我们可以简单地将请求拆分为组,做我们之前做过的事情,但是在致SelectMany的电话中,我们完成了! Rx救援!

对于Rx来说,我现在最喜欢的解决方案可能就是将它用作事件聚合器。 看看这里:

http://jfromaniello.blogspot.com/2010/04/event-aggregator-with-reactive.html

我将它改编为Silverlight,它就像一个魅力。 function强大的是过滤事件的能力。 例如,一个事件只是键入“字符串”,因为没有其他信息。 我没有为每个简单事件创建强类型类,而是创建了一个公开常量的类(因此没有魔术字符串) – 例如,BEGIN_BUSY(当调用Web服务时),END_BUSY(完成时),等等

要订阅,您可以按字面意思执行:

(from e in EventAggregator.Subscribe() where e.Equals(BEGIN_BUSY) select true).Subscribe( evt=> { // Listening only to the BEGIN_BUSY event }); 

爱它!