Rxの中身をほんのちょっと読んで見る。(その3)

動作を追う。

メソッドチェーン時(Subscribe前)

サブスクライブが走るまでは、単にIObservableを返し、生成されたオブジェクトとしては、上流のObservableと、Func<TSource, TResult>の関数を保存するだけで、これ以上のことはしません。

Subscribe時

Rxはここが重要ですよね。とりあえずsubject.Select().Subscribe(do something)みたいな感じを想定します。
また再掲まみれになりますが。。。
SelectorクラスのSubscribeが呼ばれると、Producerクラスのここが反応します。

Run(sink)は

となっており、sinkオブジェクトのRunを呼ぶのでした。Runは以下です。

またRunを呼んだときのsinkオブジェクトは、IObserverでもあるため、subscribe(safe)にわたすことができます。こうして上流のsource.Subscribe(safe)を呼び出し、どんどん上流につなげて行くことができるわけですね。なるほど。その上流で発生するIDisposableを実装しているsinkオブジェクトが返され、_upstreamにそれらの参照は保持される、と。こうしてsubscribeが上流に伝播し、根っこのsubjectなりにつながることがわかります。

Dispose時

購読停止するためSubscribe()で帰ってきたIDisposableなオブジェクトをdisposeしたときのことを考えます。リソースがどういうふうに開放されていくかは気になりますよね。Subscribeの方さへわかれば、まぁこちらは比較的カンタンで、末端のsinkオブジェクトがsubscribe時には返却されていることがわかります。そこで、SinkのDisposeがどのようになっているかをみればよく、

となります。Disposable.TryDisposeは以下のようになっていて、_upstreamのDisposeが連鎖的に呼ばれるようになっています。

とりあえずこれくらいで満足しておくこととします。

感想

だいたいの流れはわかりました。
しかしSink<TSource, TTarget>クラスのGetForwarder関数は結局一体なにものなのか、とか、safeObserver?.SetResource(sink)は一体なんの意味が…とか、まぁ気になることはこの時点でもいくつかあるのですが、まぁ初回の探索なのでまぁいいでしょう、という感じにしておきます。
だいたいのクラスの役割とか動作はわかったけど、これ一体どういう思想でこういう設計してるのかなーみたいなところがいまいち察することができないのでココらへんは精進したいですね。。。
あと非同期を考慮しているからInterlockedが頻発して大変。

neno

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

あわせて読みたい

コメントを残す

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

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