与在Visual Studio

时间:2016-11-30 13:52:01

标签: c# wpf mvvm icommand

我使用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;
    }
}

如果我从CanExcecute()类中删除 RelayCommand 方法,则exe版本会正常运行。

请有人解释为什么会发生这种事吗?是CanExecuteChanged事件处理程序吗?

1 个答案:

答案 0 :(得分:1)

您有两种选择:

  1. 请勿使用CommandManager.RequerySuggested事件。
  2. CommandManager的当前实现将所有命令的重新排序作为Dispatcher动作排列为DispatcherPriority.Background。这意味着,只要您的应用程序处于空闲状态,CommandManager就会调用您在CanExecute()中注册的所有命令的CommandManager方法。如果任何此方法确实消耗了一些资源(例如使用数据库或读取文件),那么您可能会注意到应用程序的整体性能下降。

    E.g。 Prism有自己的ICommand实现,没有订阅CommandManager的事件。这也很有效,但是当您想要更新命令状态时,必须显式调用RaiseCanExecuteChanged()方法。这通常不是问题,因为您应该只对一些命令感兴趣,而不是对应用程序中的所有命令感兴趣。

    1. 请勿在{{1​​}}方法中使用任何重量级任务。
    2. 他们应该像这样,短而快:

      CanExecute()