[原文发表时间]:Wednesday, November 18, 2009 8:05 AM
我非常高兴的宣布 .NET 的 Reactive Extensions (Rx) 预览版在MSDN DevLabs发布了。
使用Rx, 程序员能够基于我们所熟知的.NET风格和模式编写的简明的声明式代码,来设计和协调异步的和事件驱动的程序。Rx 具有坚定的理论基础,使用传统迭代(Iterator)和观察者(Observer)设计模式之间的二元性来简化异步控制。通过把LINQ的表达方式与范畴论的优雅相结合,Rx 允许程序员不用理会那些使人痛苦和不自然的行为就可以编写异步的代码。
顾名思义,反应式的程序对所在运行环境中的变化做出反应,传统上,程序员使用锁和事件句柄来协调这些变化。Rx 像push-based,或observable、集合一样为异步计算和事件建模,因此它扩大了标准LINQ 顺序运算符和扩展方法的范围,并超越了我们熟悉的基于拉的(pull-based)、或枚举、集合,进入了反应式编程领域。
实际实践
.NET的Reactive Extensions包含一系列扩展方法和为.NET 4及Silverlight 4中新加入的 IObservable<out T> 和 IObserver<in T>接口实现的LINQ标准顺序运算符。加入到.NET中的Observable接口为基于推(push-based)的通知提供了一个公共接口,并能够基于此创建.NET的一些其他功能和类库。Rx致力于事件驱动和异步计算的协调和策划,并且采用新的任务并行库作为它内部的并发机制。
Reactive Extensions可以在任何.NET语言中使用,在F#里面,最有价值的就是.NET事件。它实现了IObservable<out T>接口。除此之外,F#还提供了一些基本的函数来构造observable集合,并且F#开发人员可以使用Rx获取更加丰富的运算符来构造事件和其他observable集合。
Silverlight工具箱利用Rx为其工具箱的拖放框架提供支持,它使用一套WPF API的子集来初始化拖操作和负责与它交互。拖放框架为一些核心的控件比如Treeview, DataGrid, ListBox增加了拖放操作的支持.允许拖放操作以声明方式来描述。这在很大程度上减少了开发时间。 Silverlight异步的创造可视元素,因此我们通常需要编写异步测试代码来确保一个组件已经被正确的创建。Silverlight 单元测试框架提供的Rx功能允许开发人员编写可靠的事件处理代码而不用牺牲代码的可读性。
示例代码
下面的例子展示了一个简单的AJAX风格的反应式程序,它使用Bing的翻译服务来翻译英文并显示结果。
上图页面中的输入框设计为一个可观察的字符串集合,当用户暂停输入半秒钟左右,可以从中取得相应的字符串值。GetKeyUpEvents 扩展方法将.NET 的KeyUp事件暴露成一个可观察的集合。
IObservable<string> words = (from keyup in Input.GetKeyUpEvents() select Input.Value).Throttle(TimeSpan.FromSeconds(.5)) |
要访问Bing的翻译服务,我们只使用了一个简单的WCF服务引用。这个服务在一个函数中使用了标准的.NET BeginInvoke/EndInvoke 或事件驱动模式。而该函数通过Rx提供一个标准辅助函数返回一个Singleton的Observable集合。
IObservable<TranslationResponse> Translate(this string text, string sourceLanguage, string destinationLanguage){…} |
不同计算之间的协调工作使用了LINQ查询语句,通过发送请求到Bing的翻译服务将每一个词翻译成荷兰语、法语和西班牙语,然后使用一个连接(Join)模式等待其中最先完成的2项结果返回。
var translations = from word in words let dutch = Bing.Translate(word, "en", "nl") let french = Bing.Translate(word, "en", "fr") let spanish = Bing.Translate(word, "en", "es") from results in Observable.Join ( dutch.And(spanish).Then((d, s) => , dutch.And(french).Then((d, f) => , french.And(spanish).Then((f, s) => ).Until(words) select results; |
最后,我们订阅这个翻译结果并且一旦收到变化通知我们就更新用户界面。
translations.Subscribe(result => { Dutch.InnerText = result.Dutch.GetTranslatedTerm(); French.InnerText = result.French.GetTranslatedTerm(); Spanish.InnerText = result.Spanish.GetTranslatedTerm(); }); |
开发人员不必担心要在正确的线程里执行订阅服务,Rx运行时会负责照管这些。
更多有用的东西
除了为Observable集合提供扩展方法,Rx也包含了一系列的试验性的类型和名称空间给开发人员试验,它们为基于枚举的Observable集合实现了一些新的扩展方法,并为.NET 3.5提供了一个试验性的PLINQ。
现在就用吧
你可以从Dev Lab 下载Rx 。别忘了在项目论坛告诉我们你的想法哦,还可以去Channel 9看相关视频。
Namaste!
作者:Soma
本文链接:http://blog.joycode.com/soma/archive/2009/12/23/115822.joy
责任编辑:杜飞
关键字:.Net,技术