CanExecuteCommand是否会对性能产生影响? [英] Are there any performance implications with CanExecuteCommand?

查看:130
本文介绍了CanExecuteCommand是否会对性能产生影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用ICommand对象的CanExecuteCommand对性能有何影响?该方法是否一遍又一遍地执行?

我需要遍历约200个对象的集合,并以此为基础来决定是否应启用与Command绑定的按钮? CanExecuteCommand是否会重复执行,这会使我的应用程序变慢

解决方案

ICommand接口如下:

public interface ICommand
{
    // two methods
    bool CanExecute(object parameter);
    void Execute(object parameter);

    // one event
    event EventHandler CanExecuteChanged;
}

只要您想指示WPF应该检查/调用CanExecute方法,就应该引发CanExecuteChanged事件.实施ICommand的人应该引发事件,而需要刷新GUI(WPF系统)上的按钮启用状态的人应该注册并处理该事件,然后调用CanExecute.

在Josh Smith的RelayCommand类中,他使用WPF的内置CommandManager类来引发CanExecuteChanged:

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

从本质上讲,WPF的CommandManager是一个单例,它侦听各种路由事件:KeyUpEvent,MouseUpEvent等...,然后通过引发其RequerySuggested事件来告诉每个人嘿,发生了一件有趣的事情".因此,如果您使用的是RelayCommand,则每次CommandManager认为GUI上发生了一些有趣的事情(即使它与您的收藏无关)时,都会调用CanExecute.如果您有50条命令,则每次键入时都会重新检查所有50条命令.是的,这可能是性能问题.但是,如果CanExecute方法中的逻辑非常简单,则可能不是问题.要点:不要在CanExecute方法中进行数据库或网络API调用.

piggy带CommandManager.RequerySuggested引发ICommand.CanExecuteChanged事件的另一种方法是滚动自己的版本RelayCommand,在该版本中您自己进行检查并手动升高CanExecuteChanged,或者查看Prism框架的DelegateCommand类,它们不绑定到CommandManager,并且您必须手动引发CanExecuteChanged事件,您可以通过为PropertyChanged创建侦听器,然后在命令中引发CanExecuteChanged来完成. >

我同意上面的@Will. RelayCommand可能会在80%的时间内正常工作.如果确实开始发现性能问题,则可以创建自己的RelayCommand版本或使用Prism DelegateCommand并手动升高CanExecuteChanged.

What are the performance implications of using the CanExecuteCommand of the ICommand object. Is the method executed over and over again?

I need to iterate through a collection of about 200 objects based on which its decided whether the button bound to the Command should be enabled? Does the CanExecuteCommand get executed repeatedly which will make my application slow

解决方案

The ICommand interface is the following:

public interface ICommand
{
    // two methods
    bool CanExecute(object parameter);
    void Execute(object parameter);

    // one event
    event EventHandler CanExecuteChanged;
}

The CanExecuteChanged event should be raised any time you want to indicate that the CanExecute method should be checked/called by WPF. Whoever implements ICommand should raise the event and whoever needs to refresh the button enabled state on the GUI (the WPF system) should register for and handle the event and it calls CanExecute.

In Josh Smith's RelayCommand class, he uses WPF's built-in CommandManager class to raise CanExecuteChanged:

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

In essence, WPF's CommandManager is a singleton that listening for all sorts of routed events: KeyUpEvent, MouseUpEvent, etc... and then tells everyone "hey something interesting happened" by raising its RequerySuggested event. So if you are using RelayCommand, your CanExecute will get called every time CommandManager thinks something interesting happened on the GUI (even if it has nothing to do with your collection). If you have 50 commands, each time you key up, it's rechecking all 50 commands. So yes, this could be a performance issue. However, if your logic in your CanExecute method is really simple, it's probably a non issue. Takeaway point: don't make database or network API calls in the CanExecute method.

The alternative to piggybacking off CommandManager.RequerySuggested to raise the ICommand.CanExecuteChanged event is to roll-your-own version of RelayCommand where you do your own checking and raise CanExecuteChanged manually, or look at the Prism framework's DelegateCommand class, where they do not tie into CommandManager and you have to manually raise the CanExecuteChanged event, which you could probably do by creating a listener for PropertyChanged and then raising CanExecuteChanged on the command.

I agree with @Will above though. RelayCommand will probably work over 80% of the time without issues. If you do start finding performance issues, then you can create your own version of RelayCommand or use the Prism DelegateCommand and raise CanExecuteChanged manually.

这篇关于CanExecuteCommand是否会对性能产生影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆