Reactive Extensionsのメソッドチェーンの後ろ側が気になったので見ていく。

Rx難しいね。

Rx、使う分にはぺちぺちメソッドチェーンで幸せいっぱいなのですが、IObserverとIObservableがどういうふうに連結されていっているのかイマイチ想像がつかなかったので、オペレータ自作という形で調べてみたり動かしてみたりデバッグしてみたりしていました。

ぶっちゃけ2011年や2012年に解説記事をneueccさんxin9leさんが書いていくれているので2019年にもなって書く意味なくないかとか思いつつ、バカなので一読してもイマイチわからなかったのでデバッグしていてわかりやすいように改造しつつ、ブレイクポイント置いて眺めていたりしたのでその記録を書き記します。

今回のソースコードはこちら(github)

SelectとWhereを作ってみます。

AnonymousObserver/AnonymousObservableをやめる

AnonymousObserver/AnonymousObservableは実装にあたっては便利なのですが、型を分けたほうがデバッグ上追いやすいので名前を変えてみます。追いやすくするためだけなので実装は同じで型の名前だけ違うものをコピペ量産します。ObserverがこっちでObservableがこっち
そしてSelectとWhereの拡張メソッドを以下のようにします。

デバッグしていく。

で次のような感じで試してみます。

最後のSubscribeでは拡張メソッドを使わず、直接Observerをnewします。これもデバッグするとき何が入ってくるのか分かりやすくするため。
streamで受けているところの実態は、SelectObservableなのでそのSubscribeメソッドにブレイクポイント置いて実行してみます。

observerにEndPointObserver。ここでステップインします。

そうするとこのような感じになり、sourceがWhereObservable、observerがEndPointObserverであることが分かります。これはSelectObservableにコンストラクタでSubscribeが登録されたとき、クロージャが呼び出し元であるsourceをキャプチャしているからできることですね。クロージャありがとう。そうすると次はSelectorObserverが生成され、WhereObservableの実態であるsourceにSubscribeで渡されます。そうすると、次はMyWhereで登録したクロージャが呼ばれ、以下のような感じになります。

observerがSelectObserver、sourceがsubjectであることが分かります。これで根本であるsubjectまで大体たどり着けたので追うのはこのあたりでやめます。
こうしてSubscribeが連鎖して、末端から根本(subject)までストリームが構築されていくのが分かりました。
こうしてsubjectのOnNextが呼ばれると、それぞれのクロージャでキャプチャobserverに登録されている、observer.OnNextが発火されOnNext->OnNext->OnNext->…みたいにOnNextが連鎖していくことがわかりました。なるほどよくできてる。

感想

英知を感じた(小並感)
ここまでやってようやく冒頭のお二人が何を言っているのかを理解したのですが、Rxゴリゴリ使っている皆さんこれくらいパッと理解できてしまってるんですかね(解説記事すくない気がするし多分そういうこと)。修行が足りないなとひしひしと実感。

neno

都内のJK大学生。趣味はドールと一緒にお出かけして撮影すること。C++とC#が好き。C++は主にリアルタイム画像処理, C#はUnity, WPF, UWP, .NET Coreとかいろいろ。ASPとXamarin学習中。 専攻はCV。最近のおもちゃはHoloLens。

あわせて読みたい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

%d人のブロガーが「いいね」をつけました。