Кнопка отмены асинхронного метода (WPF-databinding comand)

Я использую предварительно закодированный ссылочный класс AsynchronousCommand для вызова моего метода, и я хотел бы использовать ту же ссылку для отмены этого метода, потому что у этого ссылочного класса уже есть некоторые методы для отмены.
Вы также можете посмотреть эти классы по ссылке:
http://pastebin.com/00eStgP6

public class AsynchronousCommand : CommandReference, INotifyPropertyChanged
    {
        public AsynchronousCommand(Action action, bool canExecute = true)
            : base(action, canExecute)
        {
            Initialise();
        }

        public AsynchronousCommand(Action<object> parameterizedAction, bool canExecute = true)
            : base(parameterizedAction, canExecute)
        {
            Initialise();
        }

        private void Initialise()
        {
            cancelCommand = new CommandReference(
          () =>
          {
              IsCancellationRequested = true;
          }, true);
        }

        public override void DoExecute(object param)
        {
            if (IsExecuting)
                return;

            CancelCommandEventArgs args = new CancelCommandEventArgs() { Parameter = param, Cancel = false };
            InvokeExecuting(args);

            if (args.Cancel)
                return;

            IsExecuting = true;

            callingDispatcher = Dispatcher.CurrentDispatcher;

            ThreadPool.QueueUserWorkItem(
            (state) =>
            {
                InvokeAction(param);

                ReportProgress(
                  () =>
                  {
                      IsExecuting = false;

                      if (IsCancellationRequested)
                          InvokeCancelled(new CommandEventArgs() { Parameter = param });
                      else
                          InvokeExecuted(new CommandEventArgs() { Parameter = param });

                      IsCancellationRequested = false;
                  }
                );
            }
          );
        }

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler propertyChanged = PropertyChanged;

            if (propertyChanged != null)
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public void ReportProgress(Action action)
        {
            if (IsExecuting)
            {
                if (callingDispatcher.CheckAccess())
                    action();
                else
                    callingDispatcher.BeginInvoke(((Action)(() => { action(); })));
            }
        }

        public bool CancelIfRequested()
        {
            if (IsCancellationRequested == false)
                return false;

            return true;
        }

        protected void InvokeCancelled(CommandEventArgs args)
        {
            CommandEventHandler cancelled = Cancelled;

            if (cancelled != null)
                cancelled(this, args);
        }

        protected Dispatcher callingDispatcher;

        private bool isExecuting = false;

        private bool isCancellationRequested;

        private CommandReference cancelCommand;

        public event PropertyChangedEventHandler PropertyChanged;

        public event CommandEventHandler Cancelled;

        public bool IsExecuting
        {
            get
            {
                return isExecuting;
            }
            set
            {
                if (isExecuting != value)
                {
                    isExecuting = value;
                    NotifyPropertyChanged("IsExecuting");
                }
            }
        }

        public bool IsCancellationRequested
        {
            get
            {
                return isCancellationRequested;
            }
            set
            {
                if (isCancellationRequested != value)
                {
                    isCancellationRequested = value;
                    NotifyPropertyChanged("IsCancellationRequested");
                }
            }
        }

        public CommandReference CancelCommand
        {
            get { return cancelCommand; }
        }
    }

Я связываю команду в представлении.

Command="{Binding ComandoProcessarArquivo}

And in my ViewModel:

private AsynchronousCommand _comandoProcessarArquivo;

public ICommand ComandoProcessarArquivo
        {
            get { return _comandoProcessarArquivo ??      (_comandoProcessarArquivo = new AsynchronousCommand(new Action(() => ProcessarArquivo()))); }
        }

private void ProcessarArquivo()
        {
    new ProcessarArquivo().Iniciar(ArquivoOrigem, ArquivoDestino, AtualizarEtapaProcesso);
}

Итак, я пытался создать кнопку отмены более 2 часов, пожалуйста, кто-нибудь может дать мне свет 😐

Спасибо!

1 ответ

  1. Я не видел эту конкретную реализацию асинхронной команды раньше, и она кажется довольно запутанной.

    Тем не менее, это подвергает второй CancelCommand. Вы не включили Xaml для кнопки отмены, но привязка должна выглядеть примерно так:

    Command="{Binding ComandoProcessarArquivo.CancelCommand}" 
    

    Если эта реализация команды-то, что вы нашли (а не стандарт компании), то я бы рекомендовал посмотреть другие варианты. Nito.AsyncEx имеет хорошую современную реализацию асинхронных команд.