Reactive Extensions(Rx) 学习
Bruce Eckel(著有多部编程书籍)和Jonas Boner(Akka的缔造者和Typesafe的CTO)发表了“反应性宣言”,在其中尝试着定义什么是反应性应用。
这样的应用应该能够:
- 对事件做出反应:事件驱动的本质,让反应性应用能够支持文中提到的若干特性。
- 对负载做出反应:聚焦于可扩展性,而不是单用户性能。
- 对失败做出反应:建立弹性系统,能够从各个层级进行恢复。
- 对用户做出反应:综合上述特征,实现交互式用户体验。
在这份宣言公布之后,Scala的创造者Martin Odersky、Reactive Extensions的创造者Erik Meijer和Akka科技公司的领导者Roland Kuhn,在Coursera上发布了一套免费课程,名为“反应性编程原理”:
该课程的目标在于讲授反应性编程的原理。反应性编程是一门新兴的学科,结合了并发、事件驱动和异步系统。对于编写任何类型的Web服务或分布式系统来说,它都至关重要;同时它在众多高性能并发系统中占有核心位置。反应性变成可以被视作高阶函数式编程对并发系统的自然拓展,通过协调和编排Actor交换的异步数据流,来处理分布的状态。
Reactive Extensions(Rx)的优点在于能够将传统的异步编程方式从支离破碎的代码调用中解放出来。Rx能够使的我们可以将异步代码写到一个单独的方法中,使得代码可读性和可维护性大大增强。
《Reactive Extensions介绍》我们了解了Rx中的一些比较重要的操作符,本文中我们将会学习如何将Reactive Extensions(Rx)应用到我们的应用程序中。
同步方法调用是阻塞式的,在很多场景下这是不合适的。我们能够用Rx改造成异步调用。一个最简单的方法就是使用IObservable.Start方法,使得Rx为我们来管理这些异步调用。
public static void ObservableStart(int x, int y)
{
PlusTwoNumberAsync(x, y).Subscribe(Console.WriteLine);
Console.ReadKey();
}
private static IObservable<int> PlusTwoNumberAsync(int x, int y)
{
return Observable.Start(() => PlusTwoNumber(x, y));
}
private static int PlusTwoNumber(int x, int y)
{
Thread.Sleep(5000);
return x + y;
}
除了Observable.Start外也可以使用Observable.Return来将同步方法改造为异步方法。只需要将上面的PlusTwoNumberAsync方法改为下面即可,运行程序的效果相同。
private static IObservable<int> PlusTwoNumberReturnAsync(int x, int y)
{
return Observable.Return(PlusTwoNumber(x, y));
}
使用SelectMany可以很方便的实现诸如在一个异步方法中调用另外一个异步方法的功能。
public static void ObservableSelectMany(int x, int y)
{
PlusTwoNumberStartAsync(x, y).SelectMany(aPlusB => MultiplyByFiveAsync(aPlusB)).Subscribe(Console.WriteLine);
}
private static IObservable<int> MultiplyByFiveAsync(int x)
{
return Observable.Return(MultiplyByFive(x));
}
private static int MultiplyByFive(int x)
{
Thread.Sleep(5000);
return x * 5;
}
完整代码如下:
// -----------------------------------------------------------------------
// <copyright file="RxAsyncCall.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace RxPractice
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive.Linq;
using System.Threading;
/// <summary>
/// 异步调用
/// </summary>
public class RxAsyncCall
{
public static void ObservableStart(int x, int y)
{
PlusTwoNumberStartAsync(x, y).Subscribe(Console.WriteLine);
}
public static void ObservableReturn(int x, int y)
{
PlusTwoNumberReturnAsync(x, y).Subscribe(Console.WriteLine);
}
public static void ObservableSelectMany(int x, int y)
{
PlusTwoNumberStartAsync(x, y).SelectMany(aPlusB => MultiplyByFiveAsync(aPlusB)).Subscribe(Console.WriteLine);
}
private static IObservable<int> PlusTwoNumberStartAsync(int x, int y)
{
return Observable.Start(() => PlusTwoNumber(x, y));
}
private static int PlusTwoNumber(int x, int y)
{
Thread.Sleep(2000);
return x + y;
}
private static IObservable<int> MultiplyByFiveAsync(int x)
{
return Observable.Return(MultiplyByFive(x));
}
private static int MultiplyByFive(int x)
{
Thread.Sleep(5000);
return x * 5;
}
private static IObservable<int> PlusTwoNumberReturnAsync(int x, int y)
{
return Observable.Return(PlusTwoNumber(x, y));
}
}
}
Implementing the GeoCoordinateWatcher as a Reactive Service
Using Reactive Extensions for Streaming Data from Database
Bing it on, Reactive Extensions! – Story, code and slides
IntroToRx.com is the online resource for getting started with the Reactive Extensions to .Net
http://blog.csdn.net/fangxinggood/article/details/7381619
- 谷歌:通往完全自动驾驶之路
- 随时随地部署Kubernetes
- 使用CoreOs,Docker和Nirmata来部署微服务风格的应用程序
- 使用ACS和Kubernetes部署Red Hat JBoss Fuse
- 教你快速安装OpenShift容器平台3.6
- 面向开发者的Cloud Foundry
- 云数据库安全与农场和餐馆:知道来源的重要性
- 云数据库安全,农场和餐馆:知道你的来源的重要性
- NO.32 不堪重负:线程池拒绝策略
- 工厂模式进阶之Android中工厂模式源码分析
- C加加游戏编程,大神十年的绝技,正确的入门,这才叫学习
- 我们应该担心吗?人工智能现在可以通过交谈来学习新单词!
- 印度财政部:比特币是纯粹投机行为 区块链资产是“庞氏骗局”
- 法律人工智能实验室成立,法官和律师会丢饭碗吗?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 极客大挑战2019-Knife
- DB2备份还原相关操作
- MySQL复制全解析 Part 8 MySQL Auto-Positioning
- Redis 5.0.8 主从搭建
- Linux 修改网卡名称及mac地址
- MySQL Galera Cluster全解析 Part 10 grastate.dat文件详解
- MySQL MHA部署 Part 7 MHA手动切换测试
- 使用sysbench进行压测 Part2 sysbench语法介绍
- mysqlbinlog命令详解 Part 1-实验环境准备
- mysqlbinlog命令详解 Part 2 -MySQL 事件类型
- mysqlbinlog命令详解 Part 4 -查看行事件具体SQL语句
- mysqlbinlog命令详解 Part 5 通过位置和时间查看日志
- mysqlbinlog命令详解 Part 6 读取远程MySQL服务器日志
- mysqlbinlog命令详解 Part 7 备份二进制日志文件
- mysqlbinlog命令详解 Part 8 指定 Server ID