2011-09-07 9 views
5

ICommand 개체의 CanExecuteCommand를 사용하여 성능에 미치는 영향은 무엇입니까? 메소드가 반복해서 실행됩니까?CanExecuteCommand에 성능 관련 문제가 있습니까?

명령에 바인딩 된 단추를 사용할지 여부를 결정하는 기준으로 약 200 개의 개체 모음을 반복해야합니까? CanExecuteCommand 내 응용 프로그램이

+4

예, 조기에 최적화하지 않은 경우에만 가능합니다. – Will

+0

댓글이 약간 모호한가요? – Tyrsius

+0

윌, 나는 또한 완전히 이해하지 못한다. 내 유효성 검사는 약 200 개의 객체 반복 트리 뷰입니다. 한 번 실행하면 시간이 많이 걸리지 않고 간단한 속성 만 확인합니다. CanExecute가 반복적으로 코드를 느리게 만드는 경우 걱정됩니다. 누군가가 약간의 빛을 던질 수 있습니까? – ganeshran

답변

13

ICommand 인터페이스를 느리게 만들 것이다 반복적으로 실행됩니까 것은 다음

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

    // one event 
    event EventHandler CanExecuteChanged; 
} 

CanExecuteChanged 이벤트는 CanExecute 방법이 선택되어야 함을 나타 내기 위해 원하는 시간을 제기해야/WPF에 의해 호출됩니다. ICommand을 구현 한 사람은 이벤트를 발생시켜야하며 GUI (WPF 시스템)에서 버튼 사용 가능 상태를 새로 고쳐야하는 사람은 이벤트를 등록하고 처리해야하며 CanExecute을 호출해야합니다. 조쉬 스미스의 RelayCommand 클래스에서

, 그는 WPF의 내장 CommandManager 클래스 CanExecuteChanged을 높이기 위해 사용 본질적으로

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

, WPF의 CommandManager는 싱글입니다 라우팅 된 모든 종류의 이벤트에 대한 수신 : KeyUpEvent, MouseUpEvent, 등등 ... 그 다음에 모두 RequerySuggested 이벤트를 제기하여 "재미있는 일이 일어났습니다."라고 말합니다. 따라서 RelayCommand을 사용하는 경우 CommandManager이 GUI에서 뭔가 재미있는 일이 일어날 때마다 호출됩니다 (컬렉션과 관련이없는 경우에도 마찬가지입니다). 명령이 50 개인 경우 키를 누를 때마다 50 개의 명령이 모두 다시 검사됩니다. 그래,이 일 수 있습니다. 성능 문제가 있습니다. 그러나 CanExecute 방법의 논리가 매우 간단하다면 문제가 아닐 수도 있습니다. 테이크 어웨이 포인트 : CanExecute 메소드에서 데이터베이스 또는 네트워크 API 호출을하지 마십시오.

ICommand.CanExecuteChanged 이벤트를 발생하는 CommandManager.RequerySuggested을 편승에 대한 대안은 당신이 당신의 자신의 검사를 할 경우 RelayCommand 버전 - 네 - 자신의 롤 수동 CanExecuteChanged 인상, 또는 프리즘 프레임 워크의 DelegateCommand 클래스, 그들은 넥타이를하지 않는 살펴 보는 것입니다 CommandManager에 입력하고 PropertyChanged에 대한 수신기를 생성 한 다음 명령에 CanExecuteChanged을 발생시켜 수동으로 CanExecuteChanged 이벤트를 발생시켜야합니다.

위의 @Will에 동의합니다. RelayCommand은 문제없이 80 % 이상의 시간 동안 작동합니다. 성능 문제를 찾기 시작하면 자체 버전의 RelayCommand를 만들거나 프리즘 DelegateCommand을 사용하여 CanExecuteChanged을 수동으로 높일 수 있습니다.

+0

관련 답변 : http://stackoverflow.com/questions/6634777/what-is-the-actual-task-of-canexecutechanged-and-commandmanager-requerysuggested – Kendrick

+0

감사합니다. Kendrick and Will, 귀하의 답변으로 요약 해드립니다. CanExecute에 넣고 성능 지연을 찾아 보겠습니다. 하나를 찾으면 다른 구현을 볼 것입니다. – ganeshran

0

미래의 Google 직원을 위해 : 다소 다른 명령 구현을 만들었습니다. 하나의 경우 ViewModelBase 클래스의 OnPropertyChanged 이벤트에 바인딩되지만 ViewModelBase 클래스의 OnPropertyChanged 이벤트에 바인딩되지만 ViewModel은 속성의 변경에 관계없이 OneWay의 경우와 마찬가지로 모든 View 인스턴스의 CanExecuteChanged 이벤트를 발생시킬 수 있습니다 원본 바인딩 시나리오로. 이 솔루션은 Nuget 및 Codeplex에서 사용할 수있는 PerrypheralFrameowrk.WPF 어셈블리의 일부입니다. 봐봐. codeplex 위키에는 자세한 설명서가 있으며 어셈블리의 클래스도 있습니다.