与在 Visual Studio 中运行相比,WPF exe 运行速度非常慢

sus*_*gos 5 c# wpf mvvm icommand

我使用 MVVM 模式在 WPF 中创建了一个应用程序。

该应用程序在 Visual Studio 调试器中运行良好,但是当我从 debug/release 文件夹运行 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我CanExcecute()从我的RelayCommand类中,那么 exe 版本将正常运行。

请任何人都可以解释为什么会发生这种情况?是用于CanExecuteChanged事件处理程序吗?

dym*_*oid 3

您有两个选择:

  1. 不要使用该CommandManager.RequerySuggested事件。

当前的实现将CommandManager所有命令的重新查询作为Dispatcher带有 的操作进行排队DispatcherPriority.Background。这意味着,只要您的应用程序空闲,就会CommandManager调用CanExecute()您在CommandManager. 如果任何这种方法确实消耗了一些资源(例如使用数据库或读取文件),那么您可能会注意到应用程序的整体性能下降。

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

  1. 不要在您的方法中使用任何重量级任务CanExecute()

它们应该是这样的,短而快:

public bool CanExecute()
{
    return this.isIdle && this.someFlag && !this.CommandAbort.CanExecute();
}
Run Code Online (Sandbox Code Playgroud)