《C#並發編程經典實例》—— 用限流和抽樣抑製事件流
聲明:本文是《C#並發編程經典實例》的樣章,感謝圖靈授權並發編程網站發布樣章,禁止以任何形式轉載此文。
問題
有時事件來得太快,這是編寫響應式代碼時經常碰到的問題。一個速度太快的事件流可導
致程序的處理過程崩潰。
解決方案
Rx 專門提供了幾個操作符,用來對付大量湧現的事件數據。Throttle 和 Sample 這兩個操 作符提供了兩種不同方法來抑製快速湧來的輸入事件。
Throttle 建立了一個超時窗口,超時期限可以設置。當一個事件到達時,它就重新開始計 時。當超時期限到達時,它就把窗口內到達的最後一個事件發布出去。
下麵的例子也是監視鼠標移動,但使用了 Throttle,在鼠標保持靜止 1 秒後才報告最近一 條移動事件。
private void Button_Click(object sender, RoutedEventArgs e) { Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( handler => (s, a) => handler(s, a), handler => MouseMove += handler, handler => MouseMove -= handler) .Select(x => x.EventArgs.GetPosition(this)) .Throttle(TimeSpan.FromSeconds(1)) .Subscribe(x => Trace.WriteLine( DateTime.Now.Second + ": Saw " + (x.X + x.Y))); }
輸出結果依賴於鼠標的實際動作,我的測試結果是這樣:
47: Saw 139
49: Saw 137
51: Saw 424
56: Saw 226
Throttle 常用於類似“文本框自動填充”這樣的場合,用戶在文本框中輸入文字,當他停 止輸入時,才需要進行真正的檢索。為抑製快速運動的事件序列,Sample 操作符使用了另一種方法。Sample 建立了一個有規律 的超時時間段,每個時間段結束時,它就發布該時間段內最後的一條數據。如果這個時間 段沒有數據,就不發布。
下麵的例子捕獲鼠標移動,每隔一秒采樣一次。 與 Throttle 不同,使用 Sample 的例子中, 不需要讓鼠標靜止一段時間,就可要看到結果。
private void Button_Click(object sender, RoutedEventArgs e) { Observable.FromEventPattern>MouseEventHandler, MouseEventArgs>( handler => (s, a) => handler(s, a), handler => MouseMove += handler, handler =>MouseMove -= handler) .Select(x => x.EventArgs.GetPosition(this)) .Sample(TimeSpan.FromSeconds(1)) .Subscribe(x => Trace.WriteLine( DateTime.Now.Second + ": Saw " + (x.X + x.Y))); }
我先讓鼠標靜止幾秒鍾,然後連續移動,得到了下麵的輸出結果:
12: Saw 311
17: Saw 254
18: Saw 269
19: Saw 342
20: Saw 224
21: Saw 277
討論
對於快速湧來的輸入,限流和抽樣是很重要的兩種工具。別忘了還有一個過濾輸入的簡單方 法, 就 是 采 用 標 準 LINQ 的 Where 操 作 符。 可 以 這 樣 說,Throttle 和 Sample 操 作 符 與
Where 基本差不多,唯一的區別是 Throttle、Sample 根據時間段過濾,而 Where 根據事件 的數據過濾。在抑製快速湧來的輸入流時,這三種操作符提供了三種不同的方法
最後更新:2017-05-23 11:02:38
上一篇:
The j.u.c Synchronizer Framework翻譯(一)背景與需求
下一篇:
《C#並發編程經典實例》—— 用窗口和緩衝對事件分組
c語言的頭文件#include <limits.h>
Windows和Linux端rsync推拉同步時中文亂碼解決方法
PgSQL · 內核開發 · 如何管理你的 PostgreSQL 插件
java中自定義annotation
中美網絡安全差距在哪裏?這要從克林頓時代說起
從一道百度麵試題到分析輸入url到頁麵返回的過程(或者查詢返回過程)
直播|排除萬難,阿裏巴巴大規模持續集成的技術演進之路
解決maven web項目倒入eclipse不出現Maven Dependencies 和 Java System Library的問題
jni使用基礎(四)之javah生成頭文件
WCF技術剖析之十一:異步操作在WCF中的應用(上篇)