We bind an execution of an asynchronous command to the ui that leads to a Task. Another command cancels this task but it doesn't work properly.
public class MainWindowViewModel : BaseViewModel
{
private IAsyncCommand _runCancelableCommand;
private ICommand _cancelCancelableCommand;
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
public IAsyncCommand RunCancelableCommand => _runCancelableCommand ??= new AsyncCommand(OnRunCancelableCommand);
public ICommand CancelCancelableCommand =>
_cancelCancelableCommand ??= new DelegateCommand(OnCancelCancelableCommand);
private void OnCancelCancelableCommand()
{
try
{
cancellationTokenSource.Cancel();
}
catch (Exception e)
{
}
// this code here is never reached
}
private async Task OnRunCancelableCommand()
{
await loadingsomedata(..., cancellationTokenSource.Token);
}
}
This actually works, the task is canceled correctly. But the code after calling Cancel is never executed. Can anyone say why.
You have not shown how you actually cancel the operation. Therefore, we can't tell whether your application deadlocks or is stuck in an infinite loop etc.
However, from the way you handle the exception it appears that you have misunderstood the flow. The exception is
OperationCancelledExceptionthrown by the code that actually executes the cancellation i.e. polls theCancellationTokenand not by the code that callsCancellationTokenSource.Cancel.Additionally, a once cancelled
CancellationTokenSourcecannot be reused. It must be disposed and a new instance must be created by the time the cancellable operation is started.The following example shows how you cancel an async operation properly: