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

我使用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();
}
点赞