Reactive Extensions(Rx)是对LINQ的一种扩展,他的目标是对异步的集合进行操作,也就是说,集合中的元素是异步填充的,比如说从Web或者云端获取数据然后对集合进行填充。Rx起源于Microsoft DevLabs小组的研究,他扩展了LINQ的一些特性,目前Rx支持多种平台如JavaScript,Windows Phone,ios,Android 。随着数据处理变得复杂,LINQ使得我们的处理逻辑变得简单清晰,同样地,随着越来越多的数据通过从云端异步获取,Rx使得这种异步数据处理操作变得简单和容易维护。

在处理静态集合数据方面,LINQ使用类似SQL的语法来操作和使用不同来源的数据。相反,Rx被设计出来用来处理将来才会填充好的集合,也就是说,集合类型定义好了,但是集合中的元素可能在未来的某一时刻才会被填充。

LINQ和Rx在技术上有很多相似的地方。在LINQ对集合进行一系列操作如添加,移除,修改,提取后,会得到一个新的集合,新集合只是原始集合的一个修改版本。Rx也是一样,集合和数据流看起来非常不同,但是他们在很多关键的地方有联系,这就是我们将数据流称之为未来的集合的原因。集合和数据流都是多数据按某种顺序进行排列。LINQ和Rx可以这些序列进行一系列操作然后得到一个新的序列。

Rx提供了一种新的组织和协调异步事件的方式,例如协调多个从云端返回的多个异步的数据流。Rx能够是的我们用一个简单的方式来处理这些数据流,极大的简化了代码的编写。例如,.NET中传统的Begin/End异步编程模式在处理单个异步操作时可以应付,但是如果同时多个异步调用时,线程控制就会使得代码变得比较复杂。使用Rx,Begin/End模式就变成了一条简单的方法,这使得代码更加清晰和容易理解。

Rx最显著的特性是使用可观察集合(Observable Collection)来达到集成异步(composing asynchronous)和基于事件(event-based)的编程的效果。Rx有一些几个特性。

  • 组合(Composing): Reactive Extension的首要目标之一就是将多种异步操作组合起来是的代码更加简单。要做到这一点,数据流必须定义清楚,这样代码就很清晰集中,使得异步操作代码异步处理代码不会充斥整个应用程序。
  • 异步(Asynchronous): 虽然Rx不仅仅能处理异步操作,但是使用Rx,大大简化了异步操作的实现,并且代码容易理解进而容易维护。
  • 基于事件(Event-based): Rx简化了传统的异步编程方式
  • 可观察集合(Observable collections): Obervable Collection是Rx的核心,它是一种集合,集合的元素在第一次访问的时候肯能还没有填充。它对与Rx的重要性类始于enumerable集合对LINQ的重要性。

下面来看看一个简单的例子来说明Rx的用法:

新建一个工程RxDemo,通过Nuget 获取Rx的最新版本:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive.Linq;
using System.IO; namespace RxDemo
{
class Program
{
static void Main(string[] args)
{
//使用Range方法返回Observable集合
IObservable<Int32> input = Observable.Range(1, 15);
input.Where(i => i % 2 == 0).Subscribe(x => Console.Write("{0} ", x));
Console.WriteLine(); //使用Array返回Observabale集合
var myArray = new[] { 1, 3, 5, 7, 9 };
IObservable<Int32> varmyObservable = myArray.ToObservable();
varmyObservable.Subscribe(x => Console.WriteLine("Integer:{0}", x));
Console.WriteLine();
//Take操作符,用来指定获取集合中的前几项
var take = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 }.ToObservable();
take.Take(5).Select(x => x * 10).Subscribe(x => Console.WriteLine(x));
Console.WriteLine();
//Skip操作符表示跳过集合中的n条记录。
var skip = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 }.ToObservable();
skip.Skip(6).Select(x => x * 10).Subscribe(x => Console.WriteLine(x));
Console.WriteLine();
//Distinct操作符用来去除集合中的非重复数据。
var distinct = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 }.ToObservable();
distinct.Distinct().Select(x => x * 10).Subscribe(x => Console.WriteLine(x));
//Rx也需要释放资源
Console.WriteLine();
var ObservableStrings = Observable.Using<char, StreamReader>(
() => new StreamReader(new FileStream("randomtext.txt", FileMode.Open)),
streamReader => (streamReader.ReadToEnd().Select(str => str)).ToObservable()
);
ObservableStrings.Subscribe(Console.Write);
Console.WriteLine();
//在Rx中Zip是将两个Observable对象合并为一个新的Observable对象。
var numberCitys = varmyObservable.Zip(input, (range, array) => range + ":" + array);
numberCitys.Subscribe(Console.WriteLine);
Console.ReadKey();
}
}
}


上述代码使用Observable.Range返回个生产Observable对象,他和Enumerable对象的Range方法含义类似,该方法接受两个参数,一个开始值,以及产生值的个数。

Mono 3.2已经包含了Rx框架,我们的代码都是Mono中执行的,看下效果:

Rx中的一些操作符和LINQ操作符有很多功能是相同的。下面对最常用的take,skip,distinct,using和zip这个操作符进行说明。

Take

Rx中的Take操作符和LINQ中的功能一样,它用来指定获取集合中的前几项。

Skip

Skip语句表示跳过集合中的n条记录。这在有些情况下非常有用,比如解析文本的时候,可能第一行是表头,所以可以使用skip跳过第一行,从第二行开始读取。还有就是在分页的时候和take一起使用非常方便。

Distinct

Distinct用来去除集合中的非重复数据。

Using

Rx也需要清理资源,当使用到了一些受限制资源或者非托管资源时,需要我们去管理这些资源的释放。

当然,我们可以调用Observable对象的一个称之为Using的静态方法。方法返回一个IObservable<char>类型对象,接受两个参数,第一个参数是一个返回StreamReaderde的Func类型参数,第二个是一个接受第一Func参数返回的StreamReader对象,返回一个类型为char的IObservable集合。

Zip

和LINQ中的Zip操作类似。LINQ中的Zip是将两个集合合并为一个新的集合,在Rx中Zip是将两个Observable对象合并为一个新的Observable对象。

Reactive Extensions入门

Reactive Extensions介绍的更多相关文章

  1. Rx (Reactive Extensions)介绍

    Reactive Extensions (Rx) 原来是由微软提出的一个综合了异步和基于事件驱动编程的库包,使用可观察序列和LINQ-style查询操作. 使用Rx, 开发者可以用Observable ...

  2. Reactive Extensions(Rx) 学习

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

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

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

  4. Reactive Extensions(Rx)并发浅析

    Reactive Extensions(Rx)并发浅析 iSun Design & Code .Net并行编程 - Reactive Extensions(Rx)并发浅析 关于Reactive ...

  5. 使用Reactive Extensions(Rx),对短时间内多次发生的事件限流

    使用Reactive Extensions(Rx),对短时间内多次发生的事件限流 牛刀小试:使用Reactive Extensions(Rx),对短时间内多次发生的事件限流 我之前有一篇文章介绍到了R ...

  6. .Net并行编程 - Reactive Extensions(Rx)并发浅析

    关于Reactive Extensions(Rx) 关于Reactive Extensions(Rx),先来看一下来自微软的官方描述: The Reactive Extensions (Rx) is ...

  7. Reactive Extensions入门

    https://www.cnblogs.com/yangecnu/archive/2012/11/03/Introducting_ReactiveExtensions.html 前面我写过7篇文章粗略 ...

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

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

  9. 2、Reactive Extensions for .NET(译)

    实验3-引入 .net 中的 events 到 Rx 目标:前面实验中的使用各种工厂构造方法创建一个 可观察序列是一个部分.把 .net 中现有的异步数据源进行关联 是更重要的事情.在这次实验中我们将 ...

随机推荐

  1. 转:WaitForSingleObject()函数、WaitForMultipleObject()函数

    http://blog.csdn.net/xiaobai1593/article/details/6672193 在多线程下面,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以 ...

  2. Android端简易蓝牙聊天通讯App(原创)

    欢迎转载,但请注明出处!谢谢.http://www.cnblogs.com/weizhxa/p/5792775.html 最近公司在做一个蓝牙串口通讯的App,有一个固定的蓝牙设备,需要实现手机连接相 ...

  3. sprint3

    Sprint 3计划会议: 团队: 郭志豪:http://www.cnblogs.com/gzh13692021053/ 杨子健:http://www.cnblogs.com/yzj666/ 刘森松: ...

  4. 【转】查询oracle比较慢的session和sql

    -查询最慢的sql select * from ( select parsing_user_id,executions,sorts command_type,disk_reads,sql_text f ...

  5. Nginx 正向代理

    目前现状:只有1个机器能上网(web),其他机器不能 方法:能上网的做一个代理web服务器中转,其他机器连接它即可.采用nginx Nginx配置如下: server{         resolve ...

  6. Java throws Exception、try、catch

    throws Exception是方法后面接的 意思是向上级抛出异常 try{}里面的异常会被外面的catch捕捉到 抛出异常是throw new Exception("异常"); ...

  7. React-native之Alert

    普通的alert 先看函数原型 alert: (title: string, message?: string, buttons?: AlertButton[], type?: string) =&g ...

  8. 两种让tableview返回顶部的方法

    1. [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_currentRow inSection:0] animat ...

  9. [Android] 多重使用Fragment 中的onFragmentInteraction

    新建的一个Fragment,被一个Activity使用,那么这个Activity需要继承一个接口: public class MainActivity extends Activity impleme ...

  10. css技巧

    1.实现position为fixed与absolute值时居中定位: 给需要定位的元素块外加一层div盒子,外层div盒子存在于文档流中,让外层div盒子居中定位并设置position属性为relat ...