Erik Meijer 和 Wes Dyer 创建了.NET 反应性框架 (Reactive Framework, Rx),即利用 LINQ to Object 的数学对偶性,允许程序员在事件使用LINQ。Erik 和Brian Beckman 证实了IObservable 是连续的Monad。
反应性编程并不是新事物。它早已经为 Cells (一种 Common Lisp 的数据流扩展),和支持高阶反应性编程的 Python 扩展 Trellis 所应用。在 C#中,程序员在指定异步操作指定回调,或事件处理程序的时候使用反应性编程。在异步操作完成或者事件触发的时候,就会调用方法并作为对该事件的反应。
LINQ to Object 使用 IEnumerable 和 IEnumerator 两个接口来迭代数据集。枚举器的 MoveNext() 方法用于从前一个元素枚举到下一个元素,而 Current 属性则用于检索个别的元素。这种机制采取广泛使用的简洁易懂的“拉(pull)”过程。Erik 还发现 IEnumerable 有对偶特性:一个是可以从集合中提取数据,同时可以把数据推进同样的集合。这意味着另一种反应性编程的方式。
理论上来说,IEnumerable 接口可对集合添加对象,但是由于它的阻塞性所以不能在异步操作中进行。那就是为什么该团队引入了两个新的接口:IObservable 和 IObserver。人们可以把 IObserver 赋给数据集并把它作为 IObservable 订阅。当一项新的数据可用时,就可以通过传递 IObservable 来把它压进集合,接着再传给 IObserver。微软展示平台控件小组的开发人员 Jafar Husain 解释 IObserver 模式的使用方法如下:
要遍历 IObservable,你需要做的就是执行与 IEnumerable 相反的操作。创建 IObserver,把它赋给 IObservable,接着 IObservable 通过调用自身的方法来把数据压进 IObserver。在 IObservable 对 Observer 调用 OnUpdate 方法的时候,就相当于 IEnumerable 方法使用关键字 yield 向 IEnumerable 传递信息。类似地,在 IObservable 对 Observer 调用 OnCompleted 方法的时候,就相当于 IEnumerable 使用关键字 break 来表示没有数据一样。
这样做的好处是什么呢?这种方法在处理事件的时候有着极大的优势。我们可以把 IObserver 附加到鼠标事件并对这些事件异步记录到一个集合当中。接着就可以使用 LINQ 来迭代数据,并进行相应的处理。要说明它在处理 GUI 事件的威力,Rx 框架已经在 Silverlight Toolkit 单元测试中使用,并包含源代码,封装在System.Reactive.dll 中。这也将会包含在.NET 4.0。
软件架构师和天文物理学家Brian Beckman 在视频采访 Erik Meijer 时,证实了 IObservable 是连续的 Monad,即 IEnumerable Monad 的对偶性。Erik 也介绍了如何通过二元化 IEnumerable 来构建 IObservable 接口。
查看英文原文: The .NET Reactive Framework (Rx) Enables LINQ over Events
评论