我使用MVVM模式在
WPF中创建了一个应用程序.
应用程序在Visual Studio调试器中正常运行,但是当我从调试/发布文件夹运行exe时,它变得非常慢.
这是我的RelayCommand类:
public class RelayCommand : ICommand
{
private readonly Action<object> execute;
private readonly Predicate<object> canExecute;
public RelayCommand(Action<object> execute) : this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
bool res = false;
if (canExecute != null)
{
res = canExecute(parameter);
}
return res;
}
public void Execute(object parameter)
{
execute(parameter);
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
如果我从我的RelayCommand类中删除CanExcecute()方法,则exe版本正常运行.
请任何人解释为什么会发生这种事情?它是否适用于CanExecuteChanged事件处理程序?
最佳答案 您有两种选择:
>不要使用CommandManager.RequerySuggested事件.
CommandManager的当前实现将所有命令的重新查询排队为具有DispatcherPriority.Background的Dispatcher操作.这意味着,只要您的应用程序处于空闲状态,CommandManager就会调用您在CommandManager中注册的所有命令的CanExecute()方法.如果任何此方法确实消耗了一些资源(例如使用数据库或读取文件),那么您可能会注意到应用程序的整体性能下降.
例如. Prism有自己的ICommand实现,无需订阅CommandManager的事件.这也很有效,但是当您想要更新命令状态时,必须显式调用RaiseCanExecuteChanged()方法.这通常不是问题,因为您应该只对一些命令感兴趣,而不是对应用程序中的所有命令感兴趣.
>不要在CanExecute()方法中使用任何重量级的任务.
它们应该像这样,短而快:
public bool CanExecute()
{
return this.isIdle && this.someFlag && !this.CommandAbort.CanExecute();
}