当我使用带有linq过滤器的Reactive Extensions(Rx)时会发生什么?
是吗,
var move = Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove");
IObservable<System.Drawing.Point> points = from evt in move
select evt.EventArgs.Location;
var overfirstbisector = from pos in points
where pos.X == pos.Y
select pos;
var movesub = overfirstbisector.Subscribe(pos => Console.WriteLine("mouse at " + pos));
从这个效率更高效?
private void MouseMove(object sender, EventArgs args)
{
if (args.Location.X == args.LocationY)
Console.WriteLine("mouse at " + args.Location);
}
我不谈论过滤逻辑本身,而是谈论方法的事件行为。 在Rx中,事件的提升方式与常规事件完全相同,但是使用了warapper或引擎盖下有什么特别之处?
答案 0 :(得分:1)
Rx查询并不比直接订阅事件更有效。在引擎盖下,Rx查询仍然订阅事件并添加一些逻辑(例如,对于调度程序),所以我会说你正在交易一点性能以提高可读性和灵活性(因为你可以快速改变和适应查询)和可测试性(因为Rx查询可以更容易地进行单元测试)。
答案 1 :(得分:1)
在这种情况下,在典型的事件处理程序中使用Rx查询没有算法性能优势 - 事实上,您的Rx查询实际上可能比典型的事件处理程序略慢。 “引擎盖下”Rx查询基本上与典型的事件处理程序做同样的事情,但是以更清洁的方式。
答案 2 :(得分:1)
Rx没有什么“特别”。 Rx只是一个库,而不是语言功能。如果你愿意的话,你可以在一个普通的旧C#项目中自己构建Rx,就好像微软的聪明人首先想到的那样。代码是开源的,所以你可以下载它,看看它是如何工作的(不可否认它在v2中变得更加复杂)
在您的示例中,Rx代码需要执行以下操作:
frm
对象IObservable<MouseEventArgs>
)
相反,非rx代码执行以下操作:
所以没有反思&amp;没有安全检查,但结果相同。在实践中,两者的性能都非常快,因此您不太可能看到任何性能差异。
关于单元测试,我认为支持或反对的任何论据都是无稽之谈。我们正在讨论MouseMove事件,你打算如何进行单元测试呢?把所有Rx放在你的代码库中似乎并不代表我自己的代价(更慢,更多代码,另一个开发理解框架等等)。