CountNotifierを使うケースで。CountNotifierは、カウントを数えるものですが、Emptyの時だけというようにSelectかましてToReactiveCommandすると、多重実行防止にも使えます。こんな感じで。
public class MainWindowViewModel { private CountNotifier ProcessCounter { get; } = new CountNotifier(); public ReactiveCommand ExecuteCommand { get; } public ReactiveProperty<string> Output { get; } public MainWindowViewModel() { this.ExecuteCommand = this.ProcessCounter .Select(x => x == CountChangedStatus.Empty) .ToReactiveCommand(); this.Output = this.ExecuteCommand .SelectMany( Observable.Using( () => this.ProcessCounter.Increment(), _ => this.HeavyTaskAsObservable())) .Select(x => x.ToString()) .ToReactiveProperty(); } // なんか重い処理 public IObservable<DateTime> HeavyTaskAsObservable() { return Observable.Return(DateTime.Now).Delay(TimeSpan.FromSeconds(5)); } }
もうちょっと単純に書くとこういう風になるかな。
public class MainWindowViewModel { private CountNotifier ProcessCounter { get; } = new CountNotifier(); public ReactiveCommand ExecuteCommand { get; } public ReactiveProperty<string> Output { get; } = new ReactiveProperty<string>(); public MainWindowViewModel() { this.ExecuteCommand = this.ProcessCounter .Select(x => x == CountChangedStatus.Empty) .ToReactiveCommand(); this.ExecuteCommand.Subscribe(async _ => { using (this.ProcessCounter.Increment()) { this.Output.Value = (await this.HeavyTaskAsync()).ToString(); } }); } // なんか重い処理 public async Task<DateTime> HeavyTaskAsync() { await Task.Delay(5000); return DateTime.Now; } }
多重起動防止用のクラスがあってもいいかもしれないですね。