Skip to main content
A newer version of this page is available. .

AsyncCommand<T> Class

An asynchronous command whose Execute(T) and CanExecute(T) delegates accept a command parameter of the T type.

Namespace: DevExpress.Mvvm

Assembly: DevExpress.WinUI.Mvvm.v22.1.dll

NuGet Package: DevExpress.WinUI

Declaration

public class AsyncCommand<T> :
    CommandBase<T>,
    IAsyncCommand,
    IDelegateCommand,
    ICommand,
    INotifyPropertyChanged

Type Parameters

Name Description
T

A command parameter of the T type.

Remarks

You can use asynchronous commands to run a time-consuming operation in a separate thread and keep the UI responsive.

For example, you can bind a button to an asynchronous command. When a user clicks the button, the command is invoked and the button becomes disabled. The rest of the interface does not freeze. When the process is done, the button is enabled.

DevExpress WinUI MVVM - AsyncCommand

Run Demo: AsyncCommand Module in the WinUI MVVM Demo

The DevExpress WinUI MVVM Framework includes the following asynchronous commands:

AsyncCommand<T>
A command whose Execute(T) and CanExecute(T) delegates accept a command parameter of the T type.
AsyncCommand
A command whose Execute and CanExecute delegates do not have a command parameter.

Create and Run Asynchronous Commands

The following code sample creates AsyncCommand and AsyncCommand<T> instances and binds them to the Button.Command property.

<Button Content="..." Command="{x:Bind MyAsyncCommand}"/>
<Button Content="..." Command="{x:Bind MyAsyncCommand}" CommandParameter="..."/>
public MyViewModel() {
    MyAsyncCommand = new AsyncCommand<string>(Calculate, CanCalculate);
}

public AsyncCommand<string> MyAsyncCommand { get; }
async Task Calculate(string parameter) {
    //...
}
bool CanCalculate(string parameter) {
    //...
}

Cancel a Command Execution

Do any of the following to cancel a command execution:

  • Call a Cancel method.
  • Call the CancelCommand.

    <Button Content="Calculate" Command="{x:Bind MyAsyncCommand}"/>
    <Button Content="Cancel" Command="{x:Bind MyAsyncCommand.CancelCommand}"/>
    <ProgressBar Value="{x:Bind Progress, Mode=OneWay}"/>
    
  • Pass a CancellationToken to the method that executes your command.

    public AsyncCommand MyAsyncCommand { get; private set; }
    
    public MyViewModel() {
        MyAsyncCommand = new AsyncCommand(Calculate);
    }
    
    async Task Calculate(CancellationToken cancellationToken) {
        for(int i = 0; i <= 100; i++) {
            cancellationToken.ThrowIfCancellationRequested();
            // ...
        }
    }
    

When a command’s cancellation process is started, the IsCancellationRequested property is set to true. When a command is executed, the IsCancellationRequested property is set to false.

Access the UI Thread from the Command

Use the IDispatcherService to access the UI thread from the command execution process.

IDispatcherService DispatcherService => GetUIService<IDispatcherService>();
async Task Calculate() {
    ...
    await DispatcherService.InvokeAsync(() => { ... });

    //or if do not need to wait for your dispatcher operation is executed:
    DispatcherService.BeginInvoke(() => { ... });
    ...
}

Simultaneous Command Execution

The AsyncCommand and AsyncCommand<T> classes contain the IsExecuting property. When the command execution is in progress, this property is set to true and the CanExecute(T) method returns false. If CanExecute(T) is false, a control that is bound to the command becomes disabled until the previous command is executed.

Set the AsyncCommand.AllowMultipleExecution constructor parameter to true to allow a user to execute a command multiple times simultaneously. In this case, the AsyncCommand.CanExecute method returns a value based on your CanExecute delegate implementation.

MyAsyncCommand = new AsyncCommand<string>(Calculate, CanCalculate, allowMultipleExecution: true);

Inheritance

See Also