ReactivePropertyのCountNotifierを再入防止に使用する
ReactiveProperty/CountNotifier.cs at master · runceel/ReactiveProperty · GitHub
「特徴的なのは、IncrementメソッドとDecrementメソッドが返すIDisposableをDisposeすることで、インクリメントやデクリメントの逆が実行されて値がもとに戻ります。」
ということは、usingが使えるので私の作ったReentrantBlockerの代わりに使えるということ・・・
のコードを例に採ると・・・
private CountNotifier blocker = new CountNotifier(1); Points .ObserveAddChangedItems() .Subscribe(vms => { vms.ToList() .ForEach(vm => { vm.X .SetValidateNotifyError(s => { NumberStyles style = NumberStyles.Number & ~NumberStyles.AllowTrailingSign; IFormatProvider provider = CultureInfo.CurrentUICulture; decimal input = decimal.Zero; if (!decimal.TryParse(s, style, provider, out input)) { return null; } var list = model.Points .Select((p, i) => { decimal value = decimal.Zero; if (Points[i] == vm) { return input; } if (Points[i].X.HasErrors && decimal.TryParse(Points[i].X.Value, style, provider, out value)) { return value; } else { return p.X.Value; } }) .ToList(); var count = list .Where(x => x == input) .Count(); if (count > 1) { return "Cannot set the duplicate X."; } else if (blocker.Count == 0) { using (blocker.Increment()) { Points .Where(p => p.X.HasErrors && (p != vm)) .ToList() .ForEach(p => p.X.ForceNotify()); } } return null; }); }); }) .AddTo(disposables);
ただ、
- ReentrantBlockerはIDisposableを実装しているけどDispose不要
- CountNotifierはDispose必要
- ReentrantBlockerの方が軽量
なので微妙だが、独自のクラスを作りたくないなら、こういう使い方も出来る。