Reactive Extensions(Rx)并发浅析
Reactive Extensions(Rx)并发浅析
iSun
Design & Code
.Net并行编程 - Reactive Extensions(Rx)并发浅析
关于Reactive Extensions(Rx)
关于Reactive Extensions(Rx),先来看一下来自微软的官方描述:
The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators. Using Rx, developers represent asynchronous data streams with Observables, query asynchronous data streams using LINQ operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, Rx = Observables + LINQ + Schedulers.
“Reactive Extensions(Rx)是一个类库,它集成了异步、基于可观察(observable)序列的事件驱动编程和LINQ-style的查询操作。使用Rx,开发人员可以用observable对象描述异步数据流,使用LINQ操作符异步查询数据和使用Schedulers控制异步过程中的并发。简而言之,Rx = Observables + LINQ + Schedulers。”
Reactive Extensions(Rx)就一定是多线程?
在以上的描述中,反复出现了一个词“异步”。一般来讲,提到“异步”,首先反应到的就是多线程。那问题来了,使用Reactive Extensions就一定意味着多线程吗?先来看一个示例,代码来了:
1 static void Main(string[] args)
2 {
3 Console.WriteLine("Starting on threadId:{0}", Thread.CurrentThread.ManagedThreadId);
4 var sub = new Subject<Object>();
5
6 sub.Subscribe(o => Console.WriteLine("Received {1} on threadId:{0}", //为Observable订阅处理器(handler),输出handler thread id
7 Thread.CurrentThread.ManagedThreadId,
8 o));
9 ParameterizedThreadStart notify = obj => //委托定义,其内输出被观察对象的thread id
10 {
11 Console.WriteLine("OnNext({1}) on threadId:{0}",
12 Thread.CurrentThread.ManagedThreadId,
13 obj);
14 sub.OnNext(obj);
15 };
16 notify(1);
17 new Thread(notify).Start(2);
18 new Thread(notify).Start(3);
19
20 Console.Read();
21 }
代码中,分别输出了通知者的thread id和callback handler的thread id。这里使用的是Rx默认的线程并发方式。输出结果如下:
无论是在当前线程调用,还是新启线程执行,通知者和处理方法所在线程均为同一个。在该示例中,Rx的线程分配是在free-threaded模式下工作的,free-threaded就意味着我们不强行指其Rx中的subscription, notification执行线程。这是Rx的默认工作模式,而这种模式下subscribing/call OnNext并没有引发新的线程来处理observable序列,线处理方式是单线程(Single Threaded Apartment,STA)。所以,我们可以这样说:单线程是Reactive Extensions(Rx)的默认处理方式。
使用SubscribeOn控制订阅(subscribing)的上下文
IObservable<TSource>的扩展方法SubscribeOn<TSource>(IScheduler)允许我们传入一调度器(Scheduler),控制订阅执行的上下文。
1 static void Main(string[] args)
2 {
3 Console.WriteLine("Starting on threadId:{0}", Thread.CurrentThread.ManagedThreadId);
4 var source = Observable.Create<int>(
5 o =>
6 {
7 Console.WriteLine("Invoked on threadId:{0}", Thread.CurrentThread.ManagedThreadId);
8 o.OnNext(1);
9 o.OnNext(2);
10 o.OnNext(3);
11 o.OnCompleted();
12 Console.WriteLine("Finished on threadId:{0}",
13 Thread.CurrentThread.ManagedThreadId);
14 return Disposable.Empty;
15 });
16 source
17 //.SubscribeOn(Scheduler.ThreadPool)
18 .Subscribe(
19 o => Console.WriteLine("Received {1} on threadId:{0}",
20 Thread.CurrentThread.ManagedThreadId,
21 o),
22 () => Console.WriteLine("OnCompleted on threadId:{0}",
23 Thread.CurrentThread.ManagedThreadId));
24 Console.WriteLine("Subscribed on threadId:{0}", Thread.CurrentThread.ManagedThreadId);
25
26 Console.Read();
27 }
代码中,使用Observable.Create创建一Observable序列,随后订阅该序列。输出结果为:
当序列被订阅source.Subscribe,代理Observable.Create被调用执行。首先是OnNext(1) handler,依次是OnNext(2) OnNext(3) handler和OnCompleted handler,最后执行到“Subscribed on threadId:10”。整个过程是线性的,阻塞(block)式的。这是符合上面分析的Rx默认单线程的模式的。
我们放开.SubscribeOn(Scheduler.ThreadPool)的注释,指定Rx工作在线程池内完成。执行结果如下:
可以看到,所有的handler都是在一新线程内完成的。这是一个非阻塞的(no=-block)模式。
SubscribeOn方法常用来指定Observable notifications的线程执行模式(哪里执行)。其常用于以下的场景中:
》 UI线程不允许阻塞
》 不需在UI线程中更新显示
常用的Scheduler属性:
CurrentThread | 在当前进程中尽快的调度工作,同步(synchronous,block) |
Immediate | 在当前进程中立即调度工作,同步(synchronous,block) |
NewThread | 在新线程中调度工作(asynchronous,no-block) |
TaskPool | 在任务工厂中调度工作(asynchronous,no-block) |
ThreadPool | 在线程池中调度工作(asynchronous,no-block) |
参考资料:
Reactive Extensions(Rx)并发浅析的更多相关文章
- Reactive Extensions(Rx) 学习
Bruce Eckel(著有多部编程书籍)和Jonas Boner(Akka的缔造者和Typesafe的CTO)发表了“反应性宣言”,在其中尝试着定义什么是反应性应用. 这样的应用应该能够: 对事件做 ...
- Reactive Extensions (Rx) 入门(5) —— Rx的事件编程
译文:https://blog.csdn.net/fangxing80/article/details/7749907 原文:http://www.atmarkit.co.jp/fdotnet/int ...
- Reactive Extensions (Rx) 入门(4) —— Rx的事件编程
译文:https://blog.csdn.net/fangxing80/article/details/7685393 原文:http://www.atmarkit.co.jp/fdotnet/int ...
- Reactive Extensions (Rx) 入门(3) —— Rx的事件编程
译文:https://blog.csdn.net/fangxing80/article/details/7628322 原文:http://www.atmarkit.co.jp/fdotnet/int ...
- Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
译文:https://blog.csdn.net/fangxing80/article/details/7581937 原文:http://www.atmarkit.co.jp/fdotnet/int ...
- Reactive Extensions (Rx) 入门(1) —— Reactive Extensions 概要
译文:https://blog.csdn.net/fangxing80/article/details/7381619 原文:http://www.atmarkit.co.jp/fdotnet/int ...
- .Net并行编程 - Reactive Extensions(Rx)并发浅析
关于Reactive Extensions(Rx) 关于Reactive Extensions(Rx),先来看一下来自微软的官方描述: The Reactive Extensions (Rx) is ...
- Rx (Reactive Extensions)介绍
Reactive Extensions (Rx) 原来是由微软提出的一个综合了异步和基于事件驱动编程的库包,使用可观察序列和LINQ-style查询操作. 使用Rx, 开发者可以用Observable ...
- Rx (Reactive Extensions)
The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using ...
随机推荐
- 交换A与B值的四种方法
在网上看到了这样一道面试题,"int A=5,int B=2,怎样交换A与B的值",或许这是一道简单到不能再简单的题,但能作为一道面试题,肯定有其独特之处 大多数人会通过定义第三个 ...
- 小代码编写神器:LINQPad 使用入门
原文:小代码编写神器:LINQPad 使用入门 一:概述 1:想查看程序运行结果,又不想启动 VS 怎么办? 2:想测试下自己的 C# 能力,不使用 VS 的智能感知,怎么办? 那么,我们有一个选择, ...
- Memcahce(MC)系列(三)Memcached它PHP转让
由PHP转让Memcahce,首先,需要在server安装Memcache,如何安装Memcache这不是本文的重点, 大约memcache安装,谁的朋友有兴趣,请参阅这里:http://blog.c ...
- hdu 4912 Paths on the tree(树链拆分+贪婪)
题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...
- 探索static——不需要能够使用该类实例?
在一般情况下.需要使用一个上课时间.你必须先实例化类,它调用的能力.在编程过程中发现.有些类不能直接实例来使用,利用其场.法等等. 这时候.靠的就是static作用.static英文意思为" ...
- compass安装使用960 Grid System
960 Grid System 是一个CSS的页面布局框架 demo: http://960.gs/demo.html 前提:安装Ruby .NodeJS 步骤1:在命令行下安装css插件: gem ...
- “采用VS2010至MFC4.2发育”最后溶液
我层2010年这方面的研究进行了简单(http://blog.csdn.net/boweirrking/article/details/5477062),那时候没有深入思考过这当中的原理,最终给出的方 ...
- 关于Java和.NET之间的通信问题(JSON)
前言: 最近项目在某XX领导的所谓指引下,非要转型Java,转就转吧,在转的过程前期是个痛苦期,特别.NET旧有项目和Java新项目需要通信时. 进入主题,Java和.NET之间需要通信,这时媒介很多 ...
- springMVC框架建设进程
1.创建Dynamic Web Project 2.导入spring和springmvc所须要的文件 3.配置web.xml文件 3.1 监听spring上下文容器 3.2 载入spring的xml文 ...
- 深入理解ASP.NET MVC Day1
深入理解ASP.NET MVC ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...