Description
One scenario that is far harder to achieve than it should be is a serial command. That is, a command that can be executed even if already executing, but latter executions automatically cancel outstanding executions. One example of where this is useful is in user-instigated searches. An existing search may be in progress, but the user may modify their query and trigger another search before the previous one completes. In such cases, the previous search operation should be null and void, supplanted by the new.
Whilst there are ways to model this using ReactiveUI today, they are both cumbersome and limited. One can create two commands - one to do the real work, and another to manage the cancellation of outstanding work before invoking the real work. It's not intuitive. Moreover, InvokeCommand
always respects CanExecute
. Since the command may already be executing, this means you can't use InvokeCommand
to trigger executions. You instead have to call Execute
yourself (which bypasses the CanExecute
check). Whilst we could instead change InvokeCommand
to permit ignoring CanExecute
, this only side-steps the smaller part of the problem - it doesn't help with the implementation of cancellation semantics.
My current thinking for resolving this is to introduce ReactiveCommand.CreateSerialFromObservable
and ReactiveCommand.CreateSerialFromTask
factory methods, which create instances of a new SerialReactiveCommand
class on behalf of the caller. The SerialReactiveCommand
class would contain the smarts for ensuring it is always executable, and that latter executions supersede any former ones.
Feedback welcome.