可能重复:
反应式扩展使用的好例子
我已经玩了一段时间的响应式扩展,但主要限于在 WPF 前端处理/组合用户驱动的事件。
这是一种非常强大的异步编程新方法,我很好奇其他人在用它做什么,你认为它可以在哪里改进我们目前做事的方式?
可能重复:
反应式扩展使用的好例子
我已经玩了一段时间的响应式扩展,但主要限于在 WPF 前端处理/组合用户驱动的事件。
这是一种非常强大的异步编程新方法,我很好奇其他人在用它做什么,你认为它可以在哪里改进我们目前做事的方式?
我们已经在两个项目(Silverlight UI)上成功使用了 RX。一开始的目的是简化 WCF 访问层)合理的是,在最坏的情况下,我们总是可以恢复到标准(回调)做事方式,而不会影响更高级别的 UI。
我们几乎不知道 RX 就像一种令人上瘾的药物——一旦你开始使用它,就再也回不来了。就像病毒一样,它从这个低级通信层迅速传播到 UI 组件:
然后是完全的投降:
好吧,你猜怎么着,有 RX 运算符;)(如果没有 - 你可以很容易地写一个)
这一切中最困难的部分是克服我们团队中的每个人一开始都经历过的那种“我的大脑很痛”的感觉。一个受多年通过这个回调编码处理我的事件的普通人的大脑与 RX 看待世界的方式不同。结果 RX 代码(尤其是当它在处理越来越复杂的场景时逐渐变得越来越密集时)对于一个毫无准备的头脑来说看起来就像一个完整的胡言乱语,有趣的是,它确实会导致一只兔子从一个看似空的帽子里拔出来。不幸的是,现实情况是在生产运行代码中没有魔法的地方,因此整个团队都必须参与进来,这意味着每个人都必须经历这个痛苦的过程,以最初看起来非常不自然的方式重新连接他们的大脑。
我想说这是人为因素,而不是 RX API 本身是有效采用 RX 的最大障碍。但是男孩值得!
我已经编写了一个更完整的库来集成 WPF / Silverlight 和 Rx,文档现在是(编辑:不再糟糕!),但您可以在以下位置查看:
Samuel McAravey在 Channel9 上有一段视频,描述了他使用 RX 构建的真实 SilverLight 应用程序。他甚至在 CodePlex 上提供了它。
此外,即使您没有异步要求,也可以应用 RX,这里有一些实际用途:
在 Silverlight 应用程序中从后端加载数据时,我们成功地使用了 Rx。我们最近从服务器上的 SOAP 服务迁移到纯 XML 生成,而 Rx 及时出现,因此我们可以使用它来代替 WebClient 或 WebRequest(实际上我们现在将 WebClient 包装在 Observable 中,但可能会转移到 WebRequest)。
几天前我们遇到了一个错误;我们意识到请求 URL 太长以至于被截断。幸运的是,我们可以将请求拆分为多个请求并连接响应,但是解决仅使用 WebClient 将意味着创建队列和状态机来按顺序处理请求......相反,使用 Rx 我们可以简单地将请求分成组,做我们之前做的事情,但是在调用 SelectMany 时我们就完成了!Rx 来救援!
Probably my favorite solution right now for Rx is to use it as an event aggregator. Take a look here:
http://jfromaniello.blogspot.com/2010/04/event-aggregator-with-reactive.html
I adapted this to Silverlight and it works like a charm. What is amazingly powerful is the ability to filter events. For examle, one event is just type "string" because there is no other information. Instead of creating a strongly typed class for each simple event, I created a class that exposes the constants (so there are no magic strings) - for example, BEGIN_BUSY (when a web service is being called), END_BUSY (when it's done), etc.
To subscribe, you can literally do:
(from e in EventAggregator.Subscribe<string>() where e.Equals(BEGIN_BUSY) select true).Subscribe( evt=> { // Listening only to the BEGIN_BUSY event });
Love it!