I have created an application in WPF using the MVVM pattern.
The application is running fine in the Visual Studio debugger, but when I'm running the exe from the debug/release folder, it becomes very slow.
Here is my RelayCommand
class:
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;
}
}
If I remove the CanExcecute()
method from my RelayCommand
class, then the exe version runs as normal.
Please can anyone explain why this thing is happening? Is it for the CanExecuteChanged
event handler?
You have two options:
CommandManager.RequerySuggested
event.The current implementation of the CommandManager
enqueues a requery of all commands as a Dispatcher
action with a DispatcherPriority.Background
. That means, whenever your application is idle, the CommandManager
will call the CanExecute()
methods of all commands you have registered in the CommandManager
. If any of this methods does consume some resources (like using a Database or reading a File), then you will probably notice the overall performance drop of your application.
E.g. Prism has its own implementation of the ICommand
without subscribing to the CommandManager
's event. This works great too, but you have to call the RaiseCanExecuteChanged()
methods explicitly when you want to update the command state. This is normally not a problem, since you should be interested only in a few of commands at one time, not in all the commands in your application.
CanExecute()
methods.They should be like this, short and fast:
public bool CanExecute()
{
return this.isIdle && this.someFlag && !this.CommandAbort.CanExecute();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With