44
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactivePropertyのメジャー機能以外の紹介と使いどころ考察

Posted at

はじめに

いつもお世話になっているReactivePropertyなんですけど、使い方を習熟するべく元のソースを見ていたら結構知らない機能があったため、勉強がてら投稿させていただきます。

機能確認用プロジェクト

ReactivePropertySample(github)

環境

ReactiveProperty: 5.1.1 (2018/06/21)
Prism: 6.3.0 (2017/03/25)
.NET Framework: 4.7.2

機能

ReactivePropertySlimReadOnlyReactivePropertySlim

フィールド数を最小限にしてアロケーションを抑えた(無印はバリデーション系などのためにSubjectやLazyの保持がかなりある)
内部で使ってるSubjectをやめて完全自前管理&Subscription(IDisposable)自体を連結リストのノード自身にすることで、複数Subscribeでのアロケーションをなくした
変更通知の実行をスケジューラー経由で行わず直接する(無印はデフォルトでDispatcher経由になるけれど、パフォーマンス上の問題と、厄介な挙動を時折示していた)
バリデーション系のメソッドを除去
ReactivePropertySlimからObservable Sourceを受けとる機能/コンストラクタを削除(ReadOnlyReactivePropertySlimのみがその機能を持つ)

上記の内容に反しない限り置き換えちゃっても大丈夫な気がしてます。例えば私はMVVMのModelでもReactivePropertyを使用しているのですがスケジューラ―関係やバリデーションは使っていなかったので今後はReactivePropertySlimを使用していこうかと思いました。
後はToReadOnlyReactivePropertyしていたところはToReadOnlyReactivePropertySlimに置き換えるとか。

  • 機能確認用

ReactivePropertySlim

AsyncReactiveCommand

Subscribeメソッドが非同期メソッドを受け取って、その非同期メソッドが実行中の間は自動的にCanExecuteをFalseにしてくれるというCommandです。

一度ボタンを押したら処理が終わるまでそのボタンの二度押しをできないようにできるみたいです。似たような機能に後述するBusyNotifierがありました。

  • 機能確認用

AsyncReactiveCommand

ReactiveTimer

機能は、Observable.TimerのStop/Start出来る版です。

より便利なTimerなようなのでReactivePropertyを使用しているならばこちらを使用したほうが良さそうです。

  • 機能確認用

ReactiveTimer

BooleanNotifier

  • 機能確認用

BooleanNotifier

BusyNotifier

  • 参考

ReactivePropertyで2度押し防止/ReactiveProperty v2.7.0をリリースしました

  • 機能説明

ProcessStartを実行するとtrueになり、ProcessStartの戻り値であるIDisposableをDisposeするとfalseになります。
コードで書くと

            using (this.BusyNotifier.ProcessStart())
            {
                await 重い処理Async();
            }

となります。この処理をReactiveCommandのSubscribeに書いてそのコマンドの生成を

var command = this.BusyNotifier.Select(b => !b).ToReactiveCommand()

とすれば二度押しを抑止することができます。ボタンひとつひとつを制御したい場合はAsyncReactiveCommandが有効ですが、一つボタンを押されれば全てのボタンを抑止したいときなどはBusyNotifierのほうが良さげに感じました。
もうひとつの特徴として、処理を並列で実行した場合に、全ての処理でDisposeされるまでBusyNotifierはfalseを維持し続けてくれました。自分のイメージだとTask.WhenAllの戻り値なし版みたいな感じです。それぞれの処理の戻り値には興味なくて、ただ単に非同期処理が終わったことだけが知りたい場合には有効な気がしました。(例えば画面に表示する情報を全部取得し終わってから操作可能にしたいときとか)

  • 機能確認用

BusyNotifier

CountNotifier

インクリメントとデクリメントを行うクラスです。コンストラクタでインクリメント出来る最大値を指定することもできます。IObservableとして使うことができます。CountChangedStatusはIncrementなのかDecrementなのかEmpty(0になった)のかを表すenumです。
Incrementは、IDisposableを返します。これをDisposeすることで、Incrementを取り消すこともできます。IncrementとDecrementは、引数に数値を渡すことで像現地を指定することができます。

単純にカウンターしても使用できそうですし、CountChangedStatusを監視していればIncrementからDecrementに変化したときだけ(逆もまた然り)を検出できそうです。

  • 機能確認用

CountNotifier

MessageBroker

  • 参考

ReactiveProperty v2.7.4をリリースしました

  • 機能説明

Messengerパターンを実現できます。PrismのEventAggregatorでも同じことが実現できました。MessageBrokerのほうは購読後すぐにRxにつなげたりできます。あと呼び出しがシングルトンでした。

  • 機能確認用

MessageBroker

ScheduledNotifier

  • 参考

ReactivePropertyのNotifier系クラス
ReactiveProperty : WPF/SL/WP7のためのRxとMVVMを繋ぐ拡張ライブラリ

  • 機能説明

SubjectISchedulerを合わせたような機能です。OnNextを任意の時間後に発行できます。あとIProgressも実装しているので進捗専用ならSubjectよりこれを使ったほうが良さそうです。

  • 機能確認用

ScheduledNotifier

Pairwise

以下のショートカットです。
ox.Zip(ox.Skip(1), (x, y) => new OldNewPair(x, y))
OldNewPair型はOldItem, NewItemで値にアクセスできます。

たまに前後値を比較したいときがあるので重宝しています。ひとつskipした同じものをzipして~というのは解っている人がみればわかるんでしょうけどもぱっとみ意図が解りづらいので、Pairwiseという名前を付けてくれたのは共通認識の点で助かります。

  • 機能確認用

Pairwise

ReactivePropertyMode

  • 参考

MVVMをリアクティブプログラミングで快適にReactivePropertyオーバービュー
ReactiveProperty v5.1.1 をリリースしました

  • 機能説明

ReactivePropertyReactivePropertySlimを初期化するときにReactivePropertyModeを指定することで挙動を変更することができます。

ReactivePropertyMode

要素 説明
None 指定なし
DistinctUntilChanged この要素を追加すると、同じ値がきたら発火しない。どんな値でも漏らさず流したいなら外した方が良い
RaiseLatestValueOnSubscribe Subscribeしたときの最初の一回を実行するか否かを指定できる。設定だけして今までのは流したくないなら外した方が良い
IgnoreInitialValidationError SetValidateNotifyError等を設定しておいて最初の一回目のエラーは無視したい場合には追加した方が良い(例えば空の入力を許さないTextBoxだけど画面表示時はエラー表示を出したくないとか)
Default DistinctUntilChanged と RaiseLatestValueOnSubscribe
  • 機能確認用

ReactivePropertyMode

44
52
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?