This post is a continuation on the UI Command Pattern : Part I where I go through different approaches for ICommand implementation with pros and cons.

I left out MvvmCross Command implementation in that post but now I have updated the sample application with MvxAsyncCommand . You can follow along with the same project from here: https://github.com/keozx/CleanRx/tree/master/src/samples/Commands

Comparison

Since my winner from last post is ReactiveCommand I present a framework command comparison including ReactiveCommand , AsyncCommand and MvxAsyncCommand given that to my surprise, MvvmCross has a very nice implementation of the Command, though still lacking of course the great versatility of ReactiveCommand but nonetheless a good option.

FeatureAsyncMvxAsyncReactive
Executes a simple bindable Action✔️✔️✔️ <T>
Create from Task<T> (not async void)✔️✔️✔️
Retrieve unhandled exceptions✔️✔️
Observes boolean changes for "CanExecute" behavior through INPC (not RaiseCanExecute)✔️ *WhenAnyValue
Observes IObservable ticks for "CanExecute" behavior✔️
Guards against double execution (double tap)✔️✔️
Returns a <T> result at end of execution✔️
Accessible "CanExecute" state✔️
Accessible "IsExecuting" state✔️
Subscribe to Completion and executes handler for <T> result

Cons

The biggest downside of MvxCommand is the lack of handling errors like AsyncCommand does, so if we want to handle unhandled exceptions we have to wrap it ourselves.

Pros

There is an overload constructor that takes a CancellationToken for the function being executed so you can cancel the task at a later point, this token is autogenerated so to cancel it from a button for example I think is not straightforward, still, this is not as interesting as the way ReactiveCommand handles cancellation in a functional state pulling way.

One of the great things of MvxCommand and MvxAsyncCommand is the ability to pass a boolean on instantiation, to indicate whether or not concurrent execution is allowed for a given command, this mimics ReactiveCommand double tap protection. Unfortunately that's all the advantage we have over AsyncCommand .

Conclusion

The ICommand implementation still has a winner in ReactiveCommand even though all the features are only accessible through the base and not only the interface, I think all is moving away from ICommand anyway, just look at how things are going in MAUI + MVU for example, is time for new UI paradigms and more efficient patterns. This is an exciting time for innovation, in the meantime let's make it all reactive!

This post is also available on DEV.