1. 什麼是LINQ和Rx
1.1 什麼是LINQ
LINQ是.NET的一個擴充套件,專門用來對資料集合,關係資料,XML檔案等物件進行查詢和提取資料
1.2 什麼是Rx
Rx提供了一種新的組織和協調非同步事件的方式,例如協調多個從雲端返回的多個非同步的資料流。Rx能夠是的我們用一個簡單的方式來處理這些資料流,極大的簡化了程式碼的編寫。例如,.NET中傳統的Begin/End非同步程式設計模式在處理單個非同步操作時可以應付,但是如果同時多個非同步呼叫時,執行緒控制就會使得程式碼變得比較複雜。使用Rx,Begin/End模式就變成了一條簡單的方法,這使得程式碼更加清晰和容易理解。
Rx最顯著的特性是使用可觀察集合(Observable Collection)來達到整合非同步(composing asynchronous)和基於事件(event-based)的程式設計的效果。Rx有一些幾個特性。
組合(Composing): Reactive Extension的首要目標之一就是將多種非同步操作組合起來是的程式碼更加簡單。要做到這一點,資料流必須定義清楚,這樣程式碼就很清晰集中,使得非同步操作程式碼非同步處理程式碼不會充斥整個應用程式。
非同步(Asynchronous): 雖然Rx不僅僅能處理非同步操作,但是使用Rx,大大簡化了非同步操作的實現,並且程式碼容易理解進而容易維護。
基於事件(Event-based): Rx簡化了傳統的非同步程式設計方式,在後面的文章中我們會看到拖放(drag and drop)模式的實現
可觀察集合(Observable collections): Obervable Collection是Rx的核心,它是一種集合,集合的元素在第一次訪問的時候肯能還沒有填充。它對與Rx的重要性類始於enumerable集合對LINQ的重要性。
2. 獲取和安裝Rx
如果使用.NET 3或者之後的版本,那麼LINQ已經整合到framework中了,同樣,如果安裝了Windows Phone開發工具,Rx的WindowsPhone版本也會自動安裝。要獲得最新的Rx可以訪問其官網(
3. Rx與LINQ的異同
在處理靜態集合資料方面,LINQ使用類似SQL的語法來操作和使用不同來源的資料。相反,Rx被設計出來用來處理將來才會填充好的集合,也就是說,集合型別定義好了,但是集合中的元素可能在未來的某一時刻才會被填充。
在使用LINQ之前要求集合中的所有元素都可以使用,也就是說在使用LINQ集合進行操作時,需要一個初始的靜態的集合。但是,問題來了,如果集合中有些資料目前還在處理之中,或者說是呼叫遠處的webservice結果還沒有返回,或者是一些實時產生的資料會不斷的往集合中新增,那麼對於這類集合LINQ不知道該怎麼處理,因為他們不是靜態的,集合中的元素會在未來的某一個時刻繼續新增,並且資料到達的事件不確定。Rx就是針對這種資料集合設定的,它是的操作這類資料集合就像LINQ操作靜態資料集合那樣簡單。
就像大家開始接觸LINQ那樣會感覺不容易理解,初次接觸Rx也會有類似的問題。一旦理解和熟悉了Rx的語法,就會感覺和LINQ一樣親切,一些複雜的非同步操作使用Rx可以非常簡單的實現。
LINQ和Rx在技術上有很多相似的地方。在LINQ對集合進行一系列操作如新增,移除,修改,提取後,會得到一個新的集合,新集合只是原始集合的一個修改版本。Rx也是一樣,咋一看,集合和資料流看起來非常不同,但是他們在很多關鍵的地方有聯絡,這就是我們將資料流稱之為未來的集合的原因。集合和資料流都是多資料按某種順序進行排列。LINQ和Rx可以這些序列進行一系列操作然後得到一個新的序列。
使用LINQ和Rx能夠帶給我們很多好處,他們有一下好處:
a 他們是.NET框架中的一級成員(first-class member)。Visual Studio中完全支援對LINQ和Rx的智慧感知和語法高亮。
b 他們能夠以一種統一的方式來處理各種資料來源產生的資料,這些資料來源包括資料庫或者XML檔案。
c.他們具有很強的擴充套件性。你可以編寫自己的類庫來擴充套件這些框架。
組合性。LINQ和Rx都可以將一系列複雜的操作和變化組合到一小片程式碼段中。使得程式碼更加簡潔。
d 宣告式風格。LINQ和Rx為程式設計帶來了一些函數語言程式設計的風格。
e 簡化實現。很多時候一條或者幾條LINQ,Rx語句就能輕易實現很多需要複雜和晦澀的語句才能完成的功能。
4. Rx和LINQ的簡單例子
講了這麼多,下面來看看一個簡單的例子來說明LINQ和Rx的用法。大家可能對LINQ比較熟悉,那麼先看看LINQ。
上述程式碼輸出結果:
上面例子很簡單,首先使用Enumerable物件的Range方法初始化一個list集合,然後使用LINQ的方法型表示式過濾所有偶數,LINQ語句程式碼執行返回一個IEnumerable集合,然後使用IEnumerable集合的擴充套件方法Tolist將其轉換為List集合,在呼叫ForEach方法傳入一個匿名方法將所有集合中的所有元素打印出來,整個程式碼緊湊易讀,邏輯清晰。
下面來如何使用Rx實現上述功能。要使用Rx必須新增System.Reactive.dll,預設安裝路徑下,我本機的地址為C:\Program Files\Microsoft Reactive Extensions SDK\v1.0.10621\Binaries\.NETFramework\v4.0\ System.Reactive.dll。
上述程式碼輸出結果:
程式碼輸出結果和LINQ版本的完全相同,但是程式的內在邏輯完全不同。上述程式碼中,首先使用Observable物件產生一個IObservable物件集合,然後使用Where子句過濾其中的元素,得到一個新的IObservable物件,然後對物件中的每一個元素註冊一個方法,上述程式碼中使用的是匿名方法將每個元素打印出來。當集合中有元素時,因為元素註冊了該方法,所以就會呼叫該方法把元素打印出來。
LINQ和Rx的能處理的集合型別不同導致其產生內在邏輯不同,下面先簡單瞭解一下Enumerable集合和Observable集合。
5.Enumerable集合和Observable集合
LINQ和Rx都是用來對集合進行操作。LINQ操作的集合實現了IEnumerable藉口,能夠使用foreach語句遍歷集合。而Rx操作的集合實現了IEnumerable,IQueryable集合,這樣的集合稱之為Observable集合。大家對Enumerable集合可能很熟悉,他是foreach語句的基礎,我的另一篇文章對這個有詳細介紹,這裡就不多說了,下面主要來看看Observable集合。
Rx對Observable集合進行操作,這個集合的命名是從觀察者設計模式得來的,觀察者模式的基礎是委託和事件,所以要了解這一模式需要理解委託和事件,在這裡推薦張子陽的文章C#中的委託和事件。Enumebrable集合中所有的元素在集合中都已經填充好了,是靜態的,使用者可以使用“拉”的方式從集合中遍歷元素進行處理。而Observable集合則不同,在建立該集合時,集合中的元素可能會在以後的某個時間才能新增進去。由於集合註冊了事件,一旦集合中的元素到達,就會觸發這一事件,將資訊“推”到註冊者哪裡去。