AsyncCommand using MVVM and WPF Goals


I want to be able to call async code using the MVVM pattern 
I want to
be able to add loading animations/screens without having to add
properties for each command on my viewmodels
I may want to be able to cancel these operations


This is what I came up with

public abstract class CommandBase : ICommand
{
    private readonly Func&lt;bool&gt; _canExecute;

    public CommandBase()
    {

    }

    public CommandBase(Func&lt;bool&gt; canExecute)
    {
        if (canExecute == null) throw new ArgumentNullException(nameof(canExecute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute();
    }

    public abstract void Execute(object parameter);

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }

    public event EventHandler CanExecuteChanged;
}


public class AsyncCommand : CommandBase, INotifyPropertyChanged
{
    private readonly Func&lt;CancellationToken, Task&gt; _action;

    private CancellationTokenSource _cancellationTokenSource;

    private bool _isRunning;
    public bool IsRunning
    {
        get { return _isRunning; }
        set
        {
            _isRunning = value; 
            OnPropertyChanged();
        }
    }

    private ICommand _cancelCommand;
    public ICommand CancelCommand =&gt; _cancelCommand ?? (_cancelCommand = new RelayCommand(Cancel));

    public AsyncCommand(Func&lt;CancellationToken, Task&gt; action)
    {
        if (action == null) throw new ArgumentNullException(nameof(action));
        _action = action;
    }

    public AsyncCommand(Func&lt;CancellationToken, Task&gt; action, Func&lt;bool&gt; canExecute) : base(canExecute)
    {
        if (action == null) throw new ArgumentNullException(nameof(action));
        _action = action;
    }

    private void Cancel()
    {
        _cancellationTokenSource?.Cancel();
    }

    public override async void Execute(object parameter)
    {
        IsRunning = true;
        try
        {
            using (var tokenSource = new CancellationTokenSource())
            {
                _cancellationTokenSource = tokenSource;

                await ExecuteAsync(tokenSource.Token);
            }
        }
        finally
        {
            _cancellationTokenSource = null;
            IsRunning = false;
        }
    }

    private Task ExecuteAsync(CancellationToken cancellationToken)
    {
        return _action(cancellationToken);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}


It can be used like this:

&lt;Button Content="Start" Command="{Binding UpdateDisplayTextCommand}"/&gt;
&lt;Button Content="Cancel" Command="{Binding UpdateDisplayTextCommand.CancelCommand}"/&gt;
&lt;ProgressBar IsIndeterminate="{Binding UpdateDisplayTextCommand.IsRunning}" /&gt;


Any faults on this implementation? I'm also open to ideas on features which could be added to this class.
You should avoid code duplication in constructors. For larger objects this practice can quickly spin out of control. Re-use existing constructors instead:

public AsyncCommand(Func&lt;CancellationToken, Task&gt; action) : this(action, () =&gt; true) {}


or use default parameters:

public AsyncCommand(Func&lt;CancellationToken, Task&gt; action, Func&lt;bool&gt; canExecute = null) : base(canExecute)
{
    if (action == null) throw new ArgumentNullException(nameof(action));
    _action = action;
}

public CommandBase(Func&lt;bool&gt; canExecute = null)
{
    //this also allows you to remove "_canExecute == null" check
    _canExecute = canExecute ?? () =&gt; true;
}


Also, public constructors in abstract class look weird. You should make those protected. 

Another minor thing: you have public and private members mixed together in a way, that does not make much sense. Personally, I find code easier to follow, if it has members of the same access level grouped together. But you can use any other scheme (some people like to group ICommand property with related delegate, for example), as long as it does not look random and chaotic.

P.S. If I were to use this class, I would also want to have an overloaded constructor, which takes Action&lt;CancellationToken&gt;. I don't want to manually create tasks, I want you to do it for me. I'm lazy like that. :) I would also want the command to either implement IDisposable or have a public Cancel method, so I can stop async operation programmatically. I mean I could call AsyncCommand.CancelCommand.Execute(...) but it looks ugly.