取消异步方法的按钮(wpf - 数据绑定命令)

时间:2016-09-29 18:29:35

标签: c# wpf asynchronous mvvm

我正在使用预编码的AsynchronousCommand Reference Class来调用我的方法,我想使用相同的引用来取消该方法,因为这个引用类已经有一些取消的方法。 您也可以在以下链接中查看此类: 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}

在我的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 个答案:

答案 0 :(得分:0)

之前我没有看过这个特殊的Async Command实现,而且看起来相当复杂。

也就是说,它暴露了第二个CancelCommand。您没有将Xaml包含在取消按钮中,但绑定应该类似于:

Command="{Binding ComandoProcessarArquivo.CancelCommand}" 

如果您发现此命令实现(而不是公司标准),那么我建议您查看其他选项。 Nito.AsyncEx具有良好的现代异步命令实现。