Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Rx入門

16,717 views

Published on

2012/02/11 - 2012/03/17
Hokuriku.NET C# -Rx入門- セッション資料

Published in: Technology, Sports
  • Be the first to comment

Rx入門

  1. 1. Hokuriku.NET C# Rx編 February 11 th /March 17 th , 2012 鈴木孝明
  2. 2. Agenda • • • • • • • Rxの概要 オブザーバーパターン LINQによる記述 時間/イベント/非同期のシーケンス化 HotとCold スケジューラの利用 今日のまとめ
  3. 3. さぁ、Rxの世界へ!! Rxの概要
  4. 4. Rx (Reactive Extensions) とは • 値群を時間軸に乗ったシーケンスとして捉える • 時間/イベント/非同期処理をLINQで記述 • .NET 3.5 SP1以降、SL 4以降、WP7で利用可能 • 特に非同期APIしかないSilverlight環境で威力を発揮 • Windows Phone 7にのみ標準搭載 • RxJSというJavaScript版もある • Microsoftの正式なプロジェクト
  5. 5. 時間軸を基にしたシーケンス • IObservable<T>は時間軸に乗る非同期な値群 • これに乗せられるものはすべて統一的に扱える • 例) タイマー/イベント/非同期処理 [出典] 連載 : Reactive Extensions (Rx) 入門 - @IT
  6. 6. 時間軸シーケンスのイメージ • ベルトコンベアのようなイメージで考える • • • • モノが流れてくる (= IObservable<T>からの発行) 不純物を取り除く検査が行われる (= Where) 梱包作業が行われる (= Select) 配送される (= Subscribe) Where Select
  7. 7. ライブラリの入手 • NuGet Gallery - Rx-Main より取得
  8. 8. ライブラリの入手 • ダウンロードサイト より取得 • NuGet が使えない場合
  9. 9. Rxの基本はPush通知!! オブザーバーパターン
  10. 10. オブザーバーパターンとは • 疎結合のためのデザインパターン • 具象クラス間の依存なしに状態変化を通知する • 例) データ変更 → UI更新 • データがUIを知っている設計は極めて汎用性が低い • 観測対象 (サブジェクト) と観測者 (オブザーバー) で抽象化 • 一般的にはインターフェース/イベントで実現
  11. 11. オブザーバーパターンの構成
  12. 12. 基本インターフェース • IObserver<T> : 観測者 OnNext(T value) 状態の変更を通知 OnError(Exception error) エラーの発生を通知 OnCompleted() 完了を通知 • IObservable<T> : 観測対象 Subscribe(IObserver<T> observer) 通知先を登録 • .NET Framework 4で新たに搭載された • .NET 3.5 SP1 / Silverlight 4環境ではRxライブラリが提供する • Windows Phone 7には標準搭載
  13. 13. Push型 vs Pull型 Push型 Pull型 • コネクションを張り、受信待機 • IObservable<T> • 各々必要に応じて取得しに行く • IEnumerable<T>
  14. 14. IObserver<T>の省略 • IObserver<T>を毎回実装するのは手間 • デリゲートを渡すことでオブザーバーの生成を隠蔽 拡張メソッド • 隠蔽化によってコードの見え方が変わる • 「IObserver<T>の登録」から「Subscribeで処理」へ
  15. 15. 一人二役なSubject<T> • IObservable<T>とIObserver<T>の両方を実装 • Rxにおけるイベント • いくつかの亜種がある Subject<T> BehaviorSubject<T> 最も基本的なもの 初期値ありSubject<T> ReplaySubject<T> 再発行時にリプレイ AsyncSubject<T> 非同期処理を模倣
  16. 16. IObservable<T>の生成メソッド • Observable静的クラスに数多く提供されている • IObservable<T>を毎回実装するのは手間 • 定型句なものは生成メソッドを使って楽をする Observable.Range(3, 5); 3から始まり1ずつインクリ メントされた5つの値を返す Observable.Repeat(1, 3); 1を3回発行 Observable.Create(observer => { observer.OnNext(100); observer.OnCompleted(); return () => { … }; // Disposer }; Subscribeで接続されたオブ ザーバーに対して直接値を 発行
  17. 17. 宣言的に書ける美しさ!! LINQ による記述
  18. 18. LINQスタイルでの記述 • メソッド形式 • クエリ式形式
  19. 19. Where/Selectの内部実装 • IObserver<T>で受ける • フィルタリング/射影 • IObservable<T>で返却 Source .Where(…) .Subscribe(observer);
  20. 20. 時間軸上の値を統一的に扱おう!! 時間/イベント/非同期の シーケンス化
  21. 21. イベントのシーケンス化 • EventHandler/EventHandler<T>形式から生成 • Observable.FromEventPatternメソッドを利用 • イベント通知はEventPattern<T>型 (Sender & EventArgs) で行われる • リフレクションによるオーバーロードもある • Action<T>/Func<T>など、独自形式から生成 • Observable.FromEventメソッドを利用 • 通知する型の形式変換も可能で、非常に柔軟性が高い
  22. 22. 非同期処理のシーケンス化 • ToAsync/Startメソッドでデリゲートからの生成 • 引数を与えたり、戻り値を受けることも可能 • BeginXxx/EndXxx (APMパターン) からの生成 • FromAsyncPatternメソッドを利用 • OnCompletedが呼ばれるまでが非同期処理中 • 非同期処理の結果はOnCompletedの直前にOnNextで通知される • 結果が何もない場合はUnit構造体 (voidの代替) が通知される • 実行スレッドは既定でThreadPool上 • GUIアプリの場合、このままではUIに触れないので注意
  23. 23. IObservable<T>の性質を知ろう!! HotとCold
  24. 24. Hot vs Cold Hot Observable Cold Observable • すべてのIObserver<T>に対して 一度に同じ値を送信 • それぞれのIObserver<T>に対して 個別に値を送信
  25. 25. Cold to Hot 変換 • 一時的に流れを堰き止める (IConnecableObservable<T>) • その間に支流を作り、完成したら再放流
  26. 26. Rxの柔軟性はココにあり!! スケジューラの利用
  27. 27. スケジューラの概要 • 処理をいつ/どこで実行するかを振り分ける • IObservable<T>の生成メソッドに設定して利用 • 基本的にはメソッドのオーバーロードで指定可能 • 指定しないメソッドは暗黙にデフォルトが設定される • スレッド切り替え • Observable.ObserveOnメソッドで以降の動作スレッドを変更 • 柔軟性が確保される反面、パフォーマンスが悪い • Observable.RangeはEnumerable.Rangeより数百倍遅い
  28. 28. スケジューラの種類 CurrentThreadScheduler 現在実行中のスレッド上で、キュー に登録されたものから順に処理 ImmediateScheduler 現在実行中のスレッド上で、即座に 実行 NewThreadScheduler それぞれ別スレッドで処理 EventLoopScheduler 指定されたスレッド上で処理 ThreadPoolScheduler スレッドプール上で処理 TaskPoolScheduler 指定されたTaskFactory上で処理 SynchronizationContextScheduler 指定されたSynchronizationContext に同期して処理 ControlScheduler 指定されたWinFormsコントロール のあるメッセージループで処理 DispatcherScheduler 指定されたDispatcher上で処理
  29. 29. ココだけは押さえよう!! 今日のまとめ
  30. 30. まとめ • オブザーバーパターンによるPush通知が基本 • 値群を時間軸に乗ったシーケンスとして捉える • IObservable<T>とIObserver<T>で実現される • 時間/イベント/非同期処理をLINQで記述可能 • メソッド形式/クエリ式形式どちらでも書ける • メソッド形式の方ができることは多い
  31. 31. まとめ • HotとColdという性質の違いがある • Hot : すべてのIObserver<T>に対して一度に同じ値を送信 • Cold : それぞれのIObserver<T>に対して個別に値を送信 • スケジューラで柔軟性を提供している • スレッドの切り替え • 処理順序の変更 • パフォーマンスは大幅に低下する • .NET 3.5 SP1以降、SL 4以降、WP7で利用可能
  32. 32. 参考記事 • 連載 : Reactive Extensions (Rx) 入門 • Reactive Extensions入門「まとめ」 • Reactive Extensions再入門 • Rx入門 - インデックス • neue.cc

×