Asynchronous WPF Commands

前端 未结 2 1459
有刺的猬
有刺的猬 2020-12-05 08:15

Note: The code in this question is part of deSleeper if you want the full source.

One of the things I wanted out of commands was a baked de

2条回答
  •  不思量自难忘°
    2020-12-05 08:59

    I've been able to refine the original sample down and have some advice for anyone else running into similar situations.

    First, consider if BackgroundWorker will meet the needs. I still use AsyncCommand often to get the automatic disable function, but if many things could be done with BackgroundWorker.

    But by wrapping BackgroundWorker, AsyncCommand provides command like functionality with asynchronous behavior (I also have a blog entry on this topic)

    public abstract class AsyncCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        public event EventHandler RunWorkerStarting;
        public event RunWorkerCompletedEventHandler RunWorkerCompleted;
    
        public abstract string Text { get; }
        private bool _isExecuting;
        public bool IsExecuting
        {
            get { return _isExecuting; }
            private set
            {
                _isExecuting = value;
                if (CanExecuteChanged != null)
                    CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    
        protected abstract void OnExecute(object parameter);
    
        public void Execute(object parameter)
        {   
            try
            {   
                onRunWorkerStarting();
    
                var worker = new BackgroundWorker();
                worker.DoWork += ((sender, e) => OnExecute(e.Argument));
                worker.RunWorkerCompleted += ((sender, e) => onRunWorkerCompleted(e));
                worker.RunWorkerAsync(parameter);
            }
            catch (Exception ex)
            {
                onRunWorkerCompleted(new RunWorkerCompletedEventArgs(null, ex, true));
            }
        }
    
        private void onRunWorkerStarting()
        {
            IsExecuting = true;
            if (RunWorkerStarting != null)
                RunWorkerStarting(this, EventArgs.Empty);
        }
    
        private void onRunWorkerCompleted(RunWorkerCompletedEventArgs e)
        {
            IsExecuting = false;
            if (RunWorkerCompleted != null)
                RunWorkerCompleted(this, e);
        }
    
        public virtual bool CanExecute(object parameter)
        {
            return !IsExecuting;
        }
    }
    

提交回复
热议问题