注意:本问题中的代码是deSleeper的一部分,如果您需要完整的源代码,请访问该网站。
我希望命令可以支持异步操作,并具备以下特性:按下按钮后,在命令执行期间禁用按钮并在完成后重新启用;将实际工作委托给线程池工作项来执行;最后,提供处理异步处理期间发生的任何错误的方式。
我的解决方案是一个AsyncCommand:
public abstract class AsyncCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public event EventHandler ExecutionStarting;
public event EventHandler<AsyncCommandCompleteEventArgs> ExecutionComplete;
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
{
IsExecuting = true;
if (ExecutionStarting != null)
ExecutionStarting(this, EventArgs.Empty);
var dispatcher = Dispatcher.CurrentDispatcher;
ThreadPool.QueueUserWorkItem(
obj =>
{
try
{
OnExecute(parameter);
if (ExecutionComplete != null)
dispatcher.Invoke(DispatcherPriority.Normal,
ExecutionComplete, this,
new AsyncCommandCompleteEventArgs(null));
}
catch (Exception ex)
{
if (ExecutionComplete != null)
dispatcher.Invoke(DispatcherPriority.Normal,
ExecutionComplete, this,
new AsyncCommandCompleteEventArgs(ex));
}
finally
{
dispatcher.Invoke(DispatcherPriority.Normal,
new Action(() => IsExecuting = false));
}
});
}
catch (Exception ex)
{
IsExecuting = false;
if (ExecutionComplete != null)
ExecutionComplete(this, new AsyncCommandCompleteEventArgs(ex));
}
}
public virtual bool CanExecute(object parameter)
{
return !IsExecuting;
}
}
所以问题是:这一切都必要吗?我注意到了内置的数据绑定异步支持,那为什么不支持命令执行呢?也许这与参数问题有关,这是我的下一个问题。