本文转自:http://www.cnblogs.com/hebeiDGL/p/3405175.html

实验3-引入 .net 中的 events 到 Rx

目标:前面实验中的使用各种工厂构造方法创建一个 可观察序列是一个部分。把 .net 中现有的异步数据源进行关联

是更重要的事情。在这次实验中我们将看到使用 FromEvent 操作来把 .net 中的 event 作为一个 observable 序

列导入到 Rx 。每次事件触发,一个 OnNext 消息会被传递到 observable 序列。

背景:Rx 的目标不是代替现有的异步编程模型,比如 .net 事件,异步模型或者 Task Parallel Library。这些已有

的理论通常很适合直接使用,比如在 C# 中使用 event handles。然而,使用这些低级的理论可能使程序员必须疲

惫地进行资源维护(比如事件的注销 -=)和进行重新改造(比如你知道怎样过滤一个事件吗?)。这样会使程序员

从实际问题的解决上分心。在下面的实验中,我们会展示 Rx 的强大源于何处:异步数据源的组合。

1、Windows Form 是 framework api 中包含很多事件的很好的示例。为了减少干扰,下面不会直接创建一个

Windows Form 工程而是使用一个控制台程序创建。同时需要添加 System.Windows.Forms 和

System.Drawing,也需要引入 System.Reactive 和 System.CoreEx:

2、输入下面的代码来创建一个新 form,并且通过 Application.Run 运行:

3、接下来我们会使用鼠标的 MouseMove 事件:

虽然能很好的工作,但是传统的 .net 事件有很多的限制:

1)事件隐藏了数据源。必须通过事件中的代码看到它。你以前有没有把 MouseMove 事件作为一个 Point

值的一个集合?在 Rx 的世界里,我们把 events 仅仅看作一个固有形式的 observable 序列:你的鼠标是

一个 Point 值的数据库。

2)事件不能传递出去,比如 一个产生 Point 值的事件不能传递出数据作为 GPS 的服务。深层的原因是因为

事件不是 first-class objects。在 Rx 的世界里,每一个 observable 序列可以用一个可以被传递和保持的

对象代表。

3)事件不能被容易的组合。例如,你不能雇佣一个数学家去按照一定的规则写一个可以过滤事件产生的数据

的过滤器。在 Rx 的世界里,由于 observables 的 first-class 的本质,我们可以提供如 Where 这种基本操作

4)Events 需要你手动维护,需要你记得传递给它的委托。在 Rx 的世界里,你可以得到一个 IDisposable 句柄

来 unsubscribe。

4、下面让我们看一下 Rx 的使用。我们使用 FromEvent 方法来向 Rx 导入一个事件,然后可以获得关联事件所获

得的 EventArgs对象。

我们深入的讲解一下:

1)这个 FromEventPattern 方法把指定事件转换成一个传递 IEvent 类型元素(既包含 sender 也

包含 event 参数 )的 observable 序列。把鼠标悬停在 var 关键字上,显示变量 moves 的类型:

2)当调用 Subscribe 时,一个 handler 附加到底层的事件。每次事件触发的时候,它的 sender 和

arguments 被装到一个 IEvent<MouseEventArgs> 对象中,然后被发送到它的所有的观察者

3)在 OnNext handler 里面,因为强类型,我们可以“点” 出事件的 Location 属性。

4)可以使用 FromEvent 操作返回的 IDisposable 对象进行事件句柄的清除。在 using 代码块里会自动

调用 Dispose 方法,自动清除事件句柄。

5、为了讲述更深入一些,我们看一下另一个 Windows Form 事件。首先添加一个 TextBox 控件

到这个 form 对象中:

6、重构代码,来拥有 Form 对象的 MouseMove 和 TextBox 的 TextChanged 事件。这次,我们输出

到控制台作为 log。在实验5 中我们会学到一个叫做 Do 的方法来做这件事。

从上面的代码中我们并没有获得更多。传统的 .net 事件并没有明确的展示 数据导向的本质。这个特别

的事件是一个很好的 observation 的示例:从 TextChanged 事件句柄中,当文字改变时你并没有立即

获得文字,这也是 99% 的 event 的这样做的。

最后,我们注意到 IDisposable 注册句柄的联合类型 System.Disposables 命名空间下的

CompositeDisposable 类。当它调用 dispose 方法时会释放掉 所有它包含的 IDisposable 对象。

7、下面是一段示例的输出:

结论:.NET 中的事件仅仅是一种形式的 异步数据源。为了作为 observable collections 来使用它们,Rx

提供了 FromEvent 方法。返回一个包含 Sender 和 event arguments 的 IEvent 类型的对象。

练习4 - 第一次浏览一些标准的 Query Operators

目标:把 observable 序列作为异步数据源,从而使它们可以像很多其它的数据源一样被查询。

一谈到 C# 编程中的查询,会立即想到 LINQ。在这个实验中,将演示如何使用 LINQ 语句对 observable

序列进行查询。

1、接着上面实验的代码,我们看一下刚才写的使用 FromEvent 操作引入到 Rx 的处理 UI 事件的代码:

回忆一下 moves 和 input 集合的类型都是 IObservable<IEvent<TEventArgs>> 类型的对象,TEventArgs

是从 FromEvent 中获得的参数类型。一般我们不会对捕获的 IEvent 里的参数都感兴趣,我们可以去掉多余的东西。

2、在传统的 .net event 世界里,很多人都会这样写代码:

在第一个示例中使用 if 语句进行过滤;在第二个示例中使用另一个本地变量

3、在 Rx 的这个新世界里,我们可以做得更好。因为 observable 序列可以用 IObservable<T>对象代表

它们所有我们可以为 operators 提供一整套的(扩展)方法。我们使用 LINQ 查询方法重写一下上面的事件

处理代码:

使用 C# 中的查询语句,我们去掉了 IEvent<MouseArgs> 和 IEvent<EventArgs> 数据类型,得到

更喜欢的 Point 和 string。从而我们得到我们想要的 moves 和 input 的更有意义的数据类型的 observable 序列

上面的查询语句可以简化为 query 扩展方法:

背景:把异步数据源定义为 first-class 对象的能力决定了 operators 的定义。

4、为了减少 input 序列中的噪音,我们可以轻松的过滤到鼠标移动的二分线(x 和 y坐标相等的点)。我们可以

使用 LINQ 中的  Where 关键字:

变量 moves 和 overFirstBisector 的类型都是 IObservable<Point>.

5、示例的输出如下,每个传递的鼠标 move 通知 都符合我们指定的过滤查询约束。

结论:我们可以使用连续的操作来过滤出符合我们要求的序列。LINQ 语句提供了一个简单的方式来执行

通常的操作。后面我们会继续讨论。

练习 5 - 更多的查询操作来 驯化 input

目标:observable 序列在正常使用中的行为不是很好。通常我们想获得一种形式的数据,却得到另一种数据形态。

上面的实验已经可以看出一些了。但是通常会有更多形式的病态数据源。例如,会输出重复的值。如果对于用户来说

一个源运行的太快而不好处理时?我们会在下面处理这种情形。

下面演示异步“建议列表”。一个用户在文本框中输入一个词汇,则向用户提供一个以这个词汇为开始的从 web

service 获取的“建议列表”。。为了防止 UI 卡死,我们使用异步的方式。Rx 非常适合处理这种问题。首先

看一下 TextBox 控件的行为。

1、在下面我们不再需要 MouseMove 事件:

2、

稍后继续整理翻译

微软 MSDN Rx 网址:The Reactive Extensions (Rx)

本文翻译原英文文档下载:Hands-on Lab Reactive Extensions for .NET

2、Reactive Extensions for .NET(译)相关推荐

  1. Reactive Extensions(Rx) 学习

    Bruce Eckel(著有多部编程书籍)和Jonas Boner(Akka的缔造者和Typesafe的CTO)发表了"反应性宣言",在其中尝试着定义什么是反应性应用. 这样的应用 ...

  2. Resources about Rx(Reactive Extensions)

    为什么80%的码农都做不了架构师?>>>    http://msdn.microsoft.com/en-us/library/hh242985(v=VS.103).aspx htt ...

  3. Reactive Extensions简介一

    在.Net 4.0中引入了两个新的接口用来实现观察者模式--IObservable和IObserver.IObservable是数据源,IObserver是观察者,观察者订阅数据源后,当新的数据产生时 ...

  4. Reactive Extensions for .NET (Rx)

    LINQ to Object使用IEnumerable和IEnumerator两个接口来迭代数据集.枚举器的MoveNext()方法用于从前一个元素枚举到下一个元素,而Current属性则用于检索个别 ...

  5. 微软开源Reactive Extensions

    Reactive Extensions (Rx)已经由Microsoft Open Technologies开源.这增加了它不久之后出现在Mono中的可能性. Rx是一个函数库,让人们可以利用可观察序 ...

  6. Reactive Extensions 相见恨晚的Rx.Net

    何为Reactive Extensions(Rx) Rx是一个遵循函数式编程的类库,它引用观察者以及迭代器设计模式对可观察对象产生的数据进行异步消费.使用Rx,开发人员将使用LINQ运算符操作异步数据 ...

  7. 牛刀小试:使用Reactive Extensions(Rx),对短时间内多次发生的事件限流

    我之前有一篇文章介绍到了Reactive Extension这个组件,请参考下面的文章,其中有一些基本的概念和相关的链接 牛刀小试:使用Reactive Extensions(Rx),一行代码实现多线 ...

  8. Reactive Extensions入门(4):Rx实战

    Reactive Extensions(Rx)的优点在于能够将传统的异步编程方式从支离破碎的代码调用中解放出来.传统的采用回调的异步编程方式会使得代码很零散,尤其是异步嵌套异步的时候,代码块很难管理. ...

  9. MVVM模式与Reactive Extensions 学习与思考

    MVVM来历:John Gossman 于2005写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expression Blend(即'Spark ...

最新文章

  1. Instruments--CoreAnimation页面性能调试
  2. 数据包发包工具bittwist
  3. 腾讯2020校园招聘---假期
  4. swift3.0 类字符串转类(字符串转ViewController)
  5. 《JavaScript权威指南》笔记(四)
  6. c语言汉诺塔动画程序,汉诺塔问题算法(c语言控制台动画演示版)
  7. en55032最新标准下载_欧盟多媒体设备CE认证将使用新标准EN55032
  8. c语言有趣源代码,分享一段有趣的小代码
  9. 挑战云主机战:学习使用云端服器象棋云库
  10. mailru邮箱下载_Mail.Ru邮箱ios客户端下载|Mail.Ru邮箱iphone/ipad版下载 6.2 - 跑跑车苹果网...
  11. vant 中 van-address-edit地址编辑 地址回显获取 areaCode
  12. 引导过程(修复MBR故障和GRUB鼓掌及破解密码)
  13. 构建初级前端页面重构开发环境
  14. C++ Qt 05:Qt布局管理器 - 荒 木 - 博客园
  15. 给定divId,滚动条滚到相应位置
  16. list与tuple
  17. maven中依赖变黄并提示Show vulnerabilities info for xxx.xxxx.xxxx:protobuf-java:3.11.4
  18. 一轻机器人_遨博轻型协作机器人6轴
  19. 腾讯智慧校园-获取用户列表失败
  20. 简单的理解deflate算法

热门文章

  1. Java并发机制的底层实现原理
  2. HDU - 1051 Wooden Sticks
  3. 【js细节剖析】通过=操作符为对象添加新属性时,结果会受到原型链上的同名属性影响...
  4. Spring Boot相关知识(二) Spring Boot项目启动的执行顺序和原理
  5. python smtp模块发送邮件
  6. Oracle宣称Java将每半年发布一个版本
  7. VR/AR技术依然红火:何时迎来爆发点
  8. Linux下Nagios的安装与配置
  9. Flex使用mx:Tree控件创建树(可添加和删除节点)
  10. apache 限制IP访问