2013-05-19 35 views
-1

當我使用Reactive Extensions(Rx)和linq過濾器時,發生了什麼?我需要一些關於接收行爲的解釋

是這樣的,

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中,事件的發生與普通事件的發生方式完全相同,但使用包裝器或引擎蓋下有特殊的東西?

回答

1

在這種情況下,使用典型事件處理程序的Rx查詢沒有任何算法性能優勢 - 事實上,您的Rx查詢實際上可能比典型的事件處理程序稍慢。 「引擎蓋下」Rx查詢基本上和典型的事件處理程序一樣,只是以一種更清晰的方式。

1

Rx查詢並不比直接訂閱事件更有效。在引擎蓋下,Rx查詢仍然訂閱事件並添加一些邏輯(例如調度程序),所以我會說你正在交易一點性能以提高可讀性和靈活性(因爲您可以快速更改並適應查詢)和可測試性(因爲Rx查詢可以更容易地進行單元測試)。

1

Rx沒有什麼「特別」。 Rx只是一個圖書館,而不是語言功能。如果你願意,你可以在一個普通的舊C#項目中自己構建Rx,這恰好是微軟的聰明人首先想到的。該代碼是開源的,現在這樣你就可以下載它,看看它是如何工作(當然它得到v2中的複雜得多)

在您的例子,在Rx代碼需要做到以下幾點:

  1. 反思性尋找所謂的「MouseMove事件」的frm對象上的事件
  2. 從事件
  3. 創建一個可觀察序列(IObservable<MouseEventArgs>)確保隱含的IObservable合同如安全語義該值是連續的,訂閱是線程安全等。
  4. 做健康檢查
  5. 訂閱序列(安全)
  6. 打印到控制檯,當值推。

與此相反,非RX代碼執行以下操作:

  1. 從基類
  2. 臨危虛擬呼叫確實的條件檢查
  3. 打印的值到控制檯。

所以沒有反射&沒有安全檢查,但結果相同。在實踐中,兩者的表現都會非常快,所以你不可能看到任何性能差異。

關於單元測試,我認爲任何爭論或反對的論點都是無稽之談。我們正在談論一個MouseMove事件,你將如何進行單元測試?把所有的Rx放在你的代碼庫中似乎不會爲我自己付出代價(更慢,更多的代碼,開發人員理解的另一個框架等等)。