2011-09-07 38 views
5

Ý nghĩa hiệu suất của việc sử dụng CanExecuteCommand của đối tượng ICommand là gì. Phương pháp được thực hiện lặp đi lặp lại?Có bất kỳ tác động hiệu suất nào với CanExecuteCommand không?

Tôi cần lặp lại thông qua bộ sưu tập khoảng 200 đối tượng dựa trên đó nó quyết định liệu nút được liên kết với Lệnh có được bật không? Liệu CanExecuteCommand được thực hiện lặp đi lặp lại mà sẽ làm cho ứng dụng của tôi chậm

+4

Có, nhưng chỉ khi bạn không tối ưu hóa sớm. – Will

+0

Nhận xét của bạn có hơi mơ hồ không. – Tyrsius

+0

Sẽ, tôi cũng không hoàn toàn hiểu. Xác thực của tôi là một lần lặp của khoảng 200 đối tượng - một chế độ xem dạng cây. Nó chỉ kiểm tra một thuộc tính đơn giản và không tốn nhiều thời gian khi chạy một lần. Mối quan tâm của tôi là nếu CanExecute được kích hoạt nhiều lần khiến mã chậm. Ai đó có thể vui lòng ném một số ánh sáng – ganeshran

Trả lời

13

Giao diện ICommand như sau:

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

    // one event 
    event EventHandler CanExecuteChanged; 
} 

Sự kiện CanExecuteChanged nên được nâng lên bất cứ lúc nào bạn muốn chỉ ra rằng phương pháp CanExecute nên được kiểm tra/được gọi bởi WPF. Bất cứ ai thực hiện ICommand nên nâng cao sự kiện và bất cứ ai cần phải làm mới trạng thái kích hoạt nút trên GUI (hệ thống WPF) nên đăng ký và xử lý sự kiện và nó gọi CanExecute.

Trong lớp RelayCommand Josh Smith, ông sử dụng WPF tích hợp trong CommandManager lớp để nâng cao CanExecuteChanged:

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

Về bản chất, WPF của CommandManager là một singleton mà nghe cho tất cả các loại sự kiện được định tuyến: KeyUpEvent, MouseUpEvent, vv ... và sau đó nói với mọi người "điều gì đó thú vị đã xảy ra" bằng cách tăng sự kiện RequerySuggested của nó. Vì vậy, nếu bạn đang sử dụng RelayCommand, CanExecute của bạn sẽ được gọi mỗi lần CommandManager nghĩ rằng điều gì đó thú vị đã xảy ra trên GUI (ngay cả khi nó không liên quan gì đến bộ sưu tập của bạn). Nếu bạn có 50 lệnh, mỗi khi bạn khóa, nó sẽ kiểm tra lại tất cả 50 lệnh. Vì vậy, có, có thể là sự cố về hiệu suất. Tuy nhiên, nếu logic của bạn trong phương thức CanExecute của bạn thực sự đơn giản, thì đó có thể là vấn đề không phải. Điểm Takeaway: không thực hiện cuộc gọi API cơ sở dữ liệu hoặc mạng trong phương thức CanExecute.

Cách khác để cõng tắt CommandManager.RequerySuggested để nâng cao sự kiện ICommand.CanExecuteChanged là roll-bạn-của riêng phiên bản của RelayCommand nơi bạn làm kiểm tra của riêng bạn và nâng cao CanExecuteChanged bằng tay, hoặc nhìn vào lớp DelegateCommand khuôn khổ của Prism, nơi họ không buộc vào CommandManager và bạn phải tự nâng cao sự kiện CanExecuteChanged mà bạn có thể thực hiện bằng cách tạo trình nghe cho PropertyChanged và sau đó tăng CanExecuteChanged trên lệnh.

Tôi đồng ý với @Will ở trên. RelayCommand có thể sẽ hoạt động trên 80% thời gian mà không gặp sự cố. Nếu bạn bắt đầu tìm kiếm các vấn đề về hiệu suất, thì bạn có thể tạo phiên bản RelayCommand của riêng mình hoặc sử dụng Prism DelegateCommand và tăng CanExecuteChanged theo cách thủ công.

+0

Câu trả lời liên quan ở đây: http://stackoverflow.com/questions/6634777/what-is-the-actual-task-of-canexecutechanged-and-commandmanager-requerysuggested – Kendrick

+0

Cảm ơn Kendrick và Will, câu trả lời của bạn tóm tắt nó cho tôi. Tôi sẽ đặt nó trong CanExecute và tìm bất kỳ độ trễ hiệu suất nào. Nếu tôi tìm thấy một, sau đó sẽ xem xét các triển khai khác – ganeshran

0

Đối với các nhà cung cấp dịch vụ tương lai: Tôi đã tạo một triển khai lệnh hơi khác. Đối với một, nó được ràng buộc với sự kiện OnPropertyChanged của lớp ViewModelBase, nhưng nó cũng cho phép Mô hình xem nâng cao sự kiện CanExecuteChanged cho tất cả các cá thể Command bên trong nó, bất kể thay đổi trong thuộc tính, chẳng hạn như trong trường hợp của One Way Để kịch bản ràng buộc nguồn. giải pháp này là một phần của hội đồng PerrypheralFrameowrk.WPF, có sẵn trên nuget và codeplex. Tìm kiếm. Các wiki codeplex có một tài liệu chi tiết, và do đó, làm các lớp học trong hội đồng.

Các vấn đề liên quan