using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; namespace DownKyi.Commands; public class AsyncDelegateCommand : ICommand { private readonly Func _execute; private readonly Func _canExecute; private CancellationTokenSource _cancellationTokenSource; private bool _isExecuting; public event EventHandler CanExecuteChanged; public AsyncDelegateCommand(Func execute, Func canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object parameter) { return !_isExecuting && (_canExecute?.Invoke(parameter) ?? true); } public async void Execute(object parameter) { _isExecuting = true; RaiseCanExecuteChanged(); _cancellationTokenSource = new CancellationTokenSource(); try { await _execute(parameter, _cancellationTokenSource.Token); } finally { _isExecuting = false; RaiseCanExecuteChanged(); } } public void Cancel() { _cancellationTokenSource?.Cancel(); } protected void RaiseCanExecuteChanged() { CanExecuteChanged?.Invoke(this, EventArgs.Empty); } }