Rx 處理器目錄 (Catalog of Rx operators)
目標 | 可選方式 | Rx 處理器(Operator) |
---|---|---|
創建 Observable Creating Observables | 直接創建 By explicit logic | Create Defer |
根據范圍創建 By specification | Range Repeat Generate Timer Interval Return | |
使用預設 Predefined primitives | Throw Never Empty | |
從其他類型創建 From other types | FromEventPattern FromEvent FromTask FromAsync | |
變換 Transforming | 單一值 To single value | Select Materialize/Dematerialize Timestamp TimeInterval |
展開內部的Collection 或者Observable Flattening inner collections/observables | SelectMany | |
分割成子序列 Splitting to subsequences | 根據順序或者時間 By coincidence/time | Buffer Window |
根據分組條件 By common key | GroupBy GroupByUntil | |
控制 Observer 和Observable 之間的關系 Controlling the observer- observable relationship | 從觀察者角度進行控制 The observed sequence | Take TakeUntil TakeWhile Skip SkipWhile SkipUntil StartWith |
從訂閱者角度進行控制 The subscription | Publish/PublishLast Multicast Replay RefCount Subscribe/DelaySubscription | |
組合 Combining | 多值組合 Values from multiple | CombineLatest WithLatestFrom Zip Merge GroupJoin |
每次取一個值 Values from one at a time | Concat Switch Join Amb |
前言
本書名為《Rx.NET 實戰》(Rx.NET in Action),本書很好地介紹了,在.NET 開發人員使用 Rx時,需要的細節和基礎知識。特別是,它解釋了如何將 .NET 中的大量異步類型連接到 Rx Observable(可觀察序列),以及如何處理錯誤、資源分配和并發性問題。
自問世以來,.NET Framework 一直強調異步執行和非阻塞 I/O 的重要性。通過委托,.NET Framework 從一開始就強調了高階函數式編程。通過在委托上自動定義 BeginInvoke 和 EndInvoke 方法,開發人員可以異步調用任何方法。
但是,異步操作的 BeginInvoke/EndInvoke 模式既繁瑣又冗長,因為它需要將代碼轉換為**延續傳遞(continuation-passing)**的模式。作為替代方案,.NET Framework 引入了基于事件的異步模式,該模式使用 .NET 對事件和事件處理程序的內置支持。與異步委托相比,雖然基于事件的模式向前邁進了一大步,但仍有更多的方式可以簡化開發。
在處理同步數據流這個問題上,利用 Enumerable/IEnumerator 接口,LINQ 標準查詢處理器(Operator)可以將該問題轉換成聲明式的方法進行處理,漂亮且優雅。如果我們能將事件也理解成數據流,并為事件提供一個類似 LINQ 的編程模型,豈不美哉?
當把事件用于異步調用時,我們會發現一個問題或者說是弊端,那就是大多數事件(例如鼠標點擊事件)與異步操作綁定過程中,最多只能產生一個值。如果我們能利用這一規律——即異步方法只返回一個值,然后給異步方法構建一個類似命令式編程的模型,并支持常規的類似控制流的條件、循環和異常處理,豈不更好?
事實證明,這兩個問題的答案都是肯定的! 通過使用均衡化的數學技巧,我們可以將 同步拉式流(synchronous pull-based stream) 中的 IEnumerable /IEnumerator 接口,轉換成 異步推式流(asynchronous push-based stream) 中的 IObservable /IObserver 接口。 C# 和 Visual Basic 中的 async/await 語法允許開發人員使用常規命令語法編寫同步和異步方法,而 LINQ 完全有能力支持發人員編寫同步和異步,兩種數據流的查詢。
這就是 Rx 的核心。現在,.NET 之外的許多語言都采用了 one/many混合sync/async 的模式,這使得開發人員無論使用哪種語言都能愉快地工作。
如果你是一名.NET開發人員,你一定要隨身攜帶本書,以便將 Rx.NET 用于實踐!
— 埃里克-梅耶 ERIK MEIJER
RX 的發明者,應用對偶(APPLIED DUALITY)的創始人
閱讀筆記:作者是applied duality的創始人,這個叫做applied duality公司的主頁上有張圖很有意思。
x軸黃色代表數據速率變化的大小,應該是說數據從靜態拉取(pull)變化成動態推送(push);
y軸藍色表示多樣化的變化,應該是描述數據的表達方式從外鍵/主鍵模式(fk/pk)變化到主鍵/值模式(key/value);
z軸紅色代表體量的變化,這個好理解,就是從小數據量(small)到大數據量(big);
這張圖我覺得作者想表達兩層含義:
- 作者認為Rx技術,從某種層面上可以理解為一種改良的sql技術,Rx可以適應數據的速率變化x,多樣化y,體量變化z。
- 作者認為Rx聲明式編程和Sql聲明式編程之間存在對等性,彼此在處理數據的思想上是互通的。
從主頁的介紹中能看到,作者發現時代在變化,數據逐漸從原來的靜態模式轉換成動態模式。他應該是想讓Rx技術能像Sql一樣,以一種聲明的方式讓人們去處理數據。畢竟用過Sql的人都能感受到她特殊的魅力。
序言
Reactive Extensions (Rx) for .NET 于 2009 年 11 月首次發布,其簡短描述為:"Rx 是一個 .NET 庫,允許程序員編寫簡潔的聲明式代碼,根據熟悉的 .NET 習慣和模式,來協調異步和基于事件的程序。(見 http://mng.bz/gQ31)。
我還記得我當時觀看了第一個示例,并閱讀了討論內容。這解決方案如此優雅和簡單,讓我驚嘆不已。不幸的是,當我親自嘗試使用 Rx 時,發現事情比我想象的要難得多,在反應式編程方式上,我需要重新改變我的思維模式。在那個年代,這方面的資料并不多,我不得不努力解決自己的問題,并通過大量的試錯來艱難地學習。
2012 年,在我服兵役結束并加入 CodeValue(www.codevalue.net)之后,有兩個重大項目讓我真正體會到了Rx的優勢。第一個項目是一個網絡安全應用程序,它需要對多個事件做出反應并進行協調,以便向最終用戶顯示并發的各種事件的狀態。第二個是在移動和 PC 設備上運行視頻聊天APP。視頻聊天APP對用戶登錄和退出系統等事件做出反應,且必須以不同方式,接收處理各類信息。盡管這兩個系統并不相同,但它們卻面臨同一個問題,即根據事件編寫流程。該流程涉及對接收值過濾,處理異步和并發,以及識別重復發生的事件模式,以便應用程序能夠高效、正確地做出響應。 我在這兩個系統中都引入了 Rx,這也是每個系統取得成功的原因之一。我們的工作超出了預期,也比計劃提前完成。
不過,盡管我掌握了 Rx 方面的知識,問題還是時有發生,而有關 Rx 的書籍和指南等資料卻很少。很多時候,問題的起因是我的同事們缺乏相關知識,或者出現了對我們來說很陌生的情況。幸運的是,在我找到問題根源后,問題很容易就解決了,這主要是因為 Rx 處理器的靈活性。在接下來的幾年里,我開始在博客上談論 Rx 以及它如何讓復雜問題的解決變得簡單。就在那時,我萌生了寫這本書的想法。 我的愿景是編寫一本循序漸進的指南,希望讓.NET程序員盡可能獲取到使用Rx庫和反應式編程所需的內容。我還想在書中介紹我多年來獲得的實踐經驗,以及存在的問題和解決辦法。
為了確保本書實現其目標,我付出了艱苦而細致的工作。有些章節必須重寫,有些主題必須更改,有些材料必須刪去,以便集中介紹重要的基本功能。這些辛勤工作的成果就是《Rx.NET in Action》,這是一本可以從頭到尾閱讀的書,也可以直接翻閱特定章節來解決問題或加深記憶。
Rx 是一種不斷發展的技術,也被移植到了許多其他平臺和語言上。它是一個開源項目,是 .NET 基金會(www.dotnetfoundation.org)的一部分。我希望 Rx 將成為在 .NET 中編程、組織和協調異步和基于事件的程序的實際方法,并希望本書能為你提供所需的一切,讓你為 Rx 這個令人興奮的新世界做好準備。
閱讀感悟:感謝作者對于Rx的貢獻,每每讀到前言,我也是感慨萬千,作為一個程序員能找到的Rx中文資料少之又少。境遇和作者寫書時其實是一樣的,希望本書能給更多人帶來驚喜和快樂。
致謝
謹以此書獻給我的妻子加芙列拉。 在我寫作的整個過程中,是你的支持、關愛和照顧讓我得以將這本書變成現實。我愛你,我欽佩你在我忙于寫作時所付出的許多努力。
我美麗的孩子希拉和約納坦,你們給我的生活帶來了歡樂和光明;我深愛著你們。當你們睡著時,坐在你們身邊,給了我許多章節的靈感。
感謝我的父母埃斯特和什洛莫,是他們給我買了第一臺電腦,點燃了我對計算機科學的熱情。
感謝我的表弟蓋伊,他對我的生活和我今天看待事物的方式產生了巨大影響,我的許多軟件能力都源于你的教導。
我的其他家人在我和他們聊天時,不得不忍受我的思緒飄到書上,我感謝你們所做的一切。
特別要感謝我的好朋友 Dror Helper,他在我不知情的情況下給了我很多建議,這些建議促成了這本書的誕生。
還要感謝我在 CodeValue 的所有同事,他們在整個過程中給予了我大力支持。
特別感謝 Erik Meijer 為我的書提供了精彩的前言,當然也要感謝他幫助創建了 Rx。
感謝 Manning 的員工。在編輯、制作和推廣方面與我一起工作的每個人,無論是直接的還是幕后的,都幫助我創作出了最好的圖書。這確實是一個團隊的努力。
感謝在寫作和發展過程中提供反饋意見的眾多審稿人: Bruno Sonnino、Bachir Chihani、Carsten J?rgensen、Dror Helper、Edgar Knapp、Fabrizio Cucci、Goetz Heller、Ignacio Rigoni、Jason Hales、Joel Kotarski、Jorge Branco、Mattias Lundell、Michele Mauro、Oscar Vargas、Rohit Sharma 和 Stephen Byrne。還要感謝技術校對員科迪-桑德(Cody Sand),他一絲不茍地審閱了最終稿件的示例代碼。
最后,非常感謝 Rx 團隊和貢獻者們,是他們打造了一項出色的技術。
關于本書
《Rx.NET in Action》是一本面向 .NET 開發人員的反應式擴展庫完整指南。書中提供了解釋、最佳實踐、技巧和竅門,使你能夠在應用程序中充分使用 Rx。
誰應該閱讀本書?
Rx.NET in Action 適用于編寫基于事件和異步應用程序的.NET 開發人員,他們需要對事件和基于推送的源進行強大的消費和查詢功能。
《Rx.NET in Action》也適合那些對反應式程序設計和 Rx 庫技術感到好奇,但又不急需使用的開發人員。在你的工具箱中添加 Rx 知識對未來的項目很有價值;反應式編程是一個熱門話題,在未來仍將如此。
本書主要使用 Rx 的 .NET 版本,代碼示例使用 C# 語言。熟悉 C# 的讀者可以輕松掌握。
本書適用于 .NET 支持的任何平臺(包括 .NET Core)。
本書的編排方式
全書共 11 章,分為兩個部分。
第 1 部分,介紹了反應式編程以及理解庫的功能方面所需的 .NET 技能。
- 第 1 章探討了反應式編程范式和反應式宣言概念。該章介紹了 Rx 的構建模塊,并解釋了何時以及為何要使用 Rx。
- 第 2 章是你真正接觸 Rx 的地方,也是將 Rx 融入你的應用程序所需的步驟。它展示了在應用程序中使用 Rx 的簡單案例研究,并比較了同一應用程序在使用 Rx 之前和之后的兩個版本。
- 第 3 章概述了 Rx 使用的函數式編程概念和技術,以及它們如何與 .NET 框架和 C# 語言結合使用。
第 2 部分,深入介紹了使用 Rx 所要完成的每項任務——從創建Observable
(可觀察序列)和Observer
(觀察者)對象,到控制它們的生命周期以及對在它們之上創建的查詢做出反應。
- 第 4 章介紹了創建
Observable
(可觀察序列)的方法,并展示了如何通過枚舉式和內置創建Operator(處理器)創建同步Observable
(可觀察序列)。 - 第 5 章解釋了 Rx 處理異步代碼的方式,以及如何將本地 .NET 異步類型橋接到可觀察對象中。本章還討論了異步代碼在現代應用程序中的重要性,以及如何在程序中添加周期性行為。
- 第 6 章集中討論了
Observable
(可觀察序列) 與observer
(觀察者) 的關系以及如何控制這種關系。在這一章中,我講解了針對各種場景創建observer
(觀察者)的最佳方法,以及如何限制observer
(觀察者)訂閱的生命周期。 - 第 7 章解釋了熱觀察對象和冷觀察對象的區別,并介紹了 Rx subject。 本章教你如何在
observer
(觀察者)訂閱觀察對象時控制Observable
(可觀察序列) 的狀態,以及如何在observer
(觀察者)之間共享排放。 - 第 8 章提供了 Rx 庫中提供的基本查詢處理器(Operator)目錄。Rx 通常被稱為 LINQ to Events,了解 Rx 處理器(Operator)的詳細信息將有助于你構建功能強大的查詢,從而節省你的時間和精力。
- 第 9 章延續了第 8 章的內容,展示了分割和組合
Observable
(可觀察序列)的高級方法。你將學習如何根據條件或巧合對元素進行分組,以及如何對observer
(觀察者)之間的相關性做出反應。 - 第 10 章深入探討了 Rx 并發模型和同步。我介紹了Scheduler(調度器)的概念,并解釋了 Rx 提供的Scheduler(調度器)。 然后,我將講解如何控制 Rx 查詢的時間和計算位置。
- 第 11 章教你保護 Rx 查詢免受故障影響,并對查詢處理中可能發生的錯誤做出反應。本章還介紹了管理由 Observable(可觀察序列)和 Rx 查詢消耗的資源的方法。
本書還有三個附錄:
- 附錄 A 總結了 .NET 中異步編程的概念。
- 附錄 B 介紹了 Rx Disposables 庫,并解釋了如何使用該庫提供的實用程序。
- 附錄 C 解釋了如何測試 Rx 處理器(Operator)和查詢。
本書可作為指南和參考書使用。如果你是 Rx 的新手,我建議你從頭開始閱讀。如果你已經熟悉了 Rx 概念,根據你要完成的任務閱讀特定章節可能會有所幫助。
關于代碼
本書包含許多源代碼示例,既有編號列表,也有與普通文本并列的示例。 在這兩種情況下,源代碼的格式都是固定寬度的字體,以便與普通文本區分開來。有時,代碼也以粗體顯示,以突出顯示與本章前幾步相比發生變化的代碼,例如,當新功能添加到現有代碼行時。
在許多情況下,原始源代碼都經過了重新格式化;我們添加了換行符,并重新調整了縮進,以適應書中可用的頁面空間。在極少數情況下,即使這樣做也是不夠的,因此在列表中加入了換行標記(?)。此外,源代碼中的注釋往往在正文描述代碼時從列表中刪除。許多列表都附有代碼注釋,以突出重要概念。
本書的源代碼可從出版商的網站(www.manning.com/books/rx-dot-net-in-action) 和GitHub(https://github.com/tamirdresher/RxInAction) 下載。該代碼的使用說明包含在資源庫根目錄下的 README 文件中。
在電子書中,某些列表和代碼片段使用了顏色。藍色用于表示原始類型和保存的關鍵字。 水藍色用于突出顯示用戶定義的類型,紅色用于字符串字面量。棕色用于字符串參數占位符,綠色用于注釋。一如既往,黑色為用戶代碼。
作者在線
購買《Rx.NET in Action》后,你可以免費訪問由 Manning Publications 管理的私人網絡論壇,在這里你可以對本書發表評論,提出技術問題,并從作者和其他用戶那里獲得幫助。要訪問論壇并訂閱,請將瀏覽http://www.manning.com/books/rx-dot-net-in-action。本頁提供的信息包括注冊后如何進入論壇、可獲得的幫助種類以及論壇行為規則。
Manning對讀者的承諾是提供一個場所,讓讀者個人之間以及讀者與作者之間能夠進行有意義的對話。這并不是對作者參與的具體數量的承諾,作者對作者在線論壇的貢獻仍然是自愿的(而且是無償的)。我們建議你試著向作者提出一些具有挑戰性的問題,以免他對這本書產生興趣。
對本書的興趣
題外話!只要本書還在印刷,就可以從出版商的網站上訪問作者在線論壇和以前的討論檔案。其他在線資源
如果你對 Rx 感興趣,還可以訪問 Rx 門戶網站 http://reactivex.io,它提供了一個開發者中心。其中包含有關該庫及其端口的
最新信息
Rx.NET 是一個開源項目,你可以在 https://github.com/dotnet/reactive上找到完整的代碼和討論。
如果你想咨詢有關 Rx 的問題,可以訪問 gitter 頻道(https://gitter.im/Reactive-Extensions/Rx.NET) 或slack的#rx 頻道,這需要你通過 .NET Core Slack 頻道的注冊頁面(http://tattoocoder.com/aspnet-slack-sign-up/) 進行訂閱。
關于作者
TAMIR DRESHER 是一名高級軟件架構師,在以色列的 CodeValue 公司擔任顧問。作為微軟編程社區的杰出成員,Tamir 經常在開發者會議上就軟件開發主題發表演講,并在 Ruppin 學術中心擔任軟件工程講師。
作為 .NET Framework 和軟件工藝方面的專家,Tamir 已經培訓了數百名開發人員,并為商業和公共部門的許多知名客戶提供了幫助。
自 Rx 發布以來,Tamir 一直在使用它,且愛不釋手。作為早期使用者之一,Tamir 了解 Rx 庫的內部結構,并積極地向其他開發人員介紹 Rx,幫助他們利用反應式編程的強大功能提高編程技能。
Tamir 在他的博客 www.tamirdresher.com 上講述了他的編程經歷。
關于封面插圖
《Rx.NET in Action》封面上的人物標題為 “中國僧侶或道士的習慣”。插圖選自出版商托馬斯-杰弗里斯(Thomas Jefferys)的《古今各國服飾集》(四卷)倫敦,1757 年至 1772 年間出版。扉頁上標明這些是手工上色的銅版雕刻,并用阿拉伯樹膠增色。 托馬斯-杰弗里斯(1719-1771 年)被稱為 “喬治三世的地理學家”。作為一名英國制圖師,他是當時領先的地圖供應商。他為政府和其他官方機構雕刻和印刷地圖,并制作了大量商業地圖和地圖集,尤其是北美地圖。作為一名地圖繪制者,他對所勘測地當地的服飾和風土人情產生了濃厚的興趣,他將這些都收藏在書中,內容十分精彩。
在 18 世紀晚期,以休閑為目的的出國旅行度假相對較少,于是乎像這樣的作品集便很受歡迎,它向游客和人們介紹了其他國家的居民。 杰弗里斯畫冊中圖畫豐富多彩,生動地展現了約 200 年前世界各國的異域風情。自那以后,著裝發生了變化,像當時那樣,如此豐富的地區性也逐漸消失。 現在,人們常常很難分辨出一個大洲和另一個大洲的居民。 也許,樂觀地看,我們用文化和視覺的多樣性換來了更加豐富多彩的個人生活。或者說,我們換來了更豐富多彩、更有趣的知識和技術生活。
在我們很難區分一本電腦書籍和另一本書籍的時候,Manning 用杰弗里斯的圖片還原了兩個世紀前豐富多彩的地區生活,用書籍封面頌揚了電腦行業的創造力和主動性。
Rx.NET in Action 第一章學習筆記
Rx.NET in Action 第二章學習筆記
Rx.NET in Action 第三章學習筆記
Rx.NET in Action 第四章學習筆記