2012-04-03 24 views
5

Khi thực hiện giao diện INotifyPropertyChanged ở dạng cơ bản nhất của nó, hầu hết mọi người dường như để thực hiện nó như thế này ::INotifyProperyChanged - tại sao lại chuyển nhượng thêm?

public virtual void OnPropertyChanged(string propertyName) 
{ 
    var propertyChanged = PropertyChanged; 
    if (propertyChanged != null) 
    { 
     propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Câu hỏi của tôi là: Tại sao sự phân công thêm var propertyChanged = PropertyChanged;? Nó chỉ là vấn đề ưu tiên, hay có lý do chính đáng cho nó? Chắc chắn sau đây là chỉ là hợp lệ?

public virtual void OnPropertyChanged(string propertyName) 
{ 
    if (PropertyChanged != null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+1

http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety –

Trả lời

4

Việc gán cho biến tạm thời sẽ loại bỏ cơ hội của điều kiện cuộc đua giữa kiểm tra trống và người đăng ký sự kiện cuối cùng, hủy đăng ký. Xem Nguyên tắc sự kiện .NET here.

Snip:

// Make a temporary copy of the event to avoid possibility of 
    // a race condition if the last subscriber unsubscribes 
    // immediately after the null check and before the event is raised. 
    EventHandler<CustomEventArgs> handler = RaiseCustomEvent; 
+0

Ok, do đó, đó là vấn đề an toàn của luồng. Nhưng trong một ứng dụng MVVM, tất cả các cuộc gọi này được thực hiện từ Dispatcher chính, vì vậy nó không thực sự là một vấn đề, phải không? – Per

+0

Không nhất thiết. Có, lượt xem sẽ thêm/xóa người đăng ký cho các ràng buộc của họ trên luồng GUI chính. Nhưng bạn có thể có các Mô hình khác, được tạo trên một chuỗi không phải GUI, đăng ký các thay đổi trên thuộc tính của ViewModel. Tất nhiên, điều này có thể không phải là một thực hành thiết kế tuyệt vời và có lẽ những Mô hình đó sẽ nhận được thông báo qua một Event Aggregator. –

1

Đó là cho các môi trường đa luồng, nơi mà một số chủ đề khác có thể đặt sự kiện để null trước khi nó được thực thi.

Bằng cách sử dụng biến cục bộ, điều này sẽ được ngăn chặn và các đại biểu được chỉ định sẽ vẫn được gọi.

1

Trong ứng dụng đa luồng, có thể (trong ví dụ thứ hai của bạn) giữa kiểm tra xem PropertyChanged != null (giả sử nó không phải là rỗng) và thực sự gọi đại biểu, luồng của bạn bị trống bởi người khác chưa đăng ký số cuối cùng là trình xử lý sự kiện từ người được ủy quyền. Sau đó, khi chuỗi ban đầu tiếp tục và gọi số PropertyChanged(this, new PropertyChangedEventArgs(propertyName));, nó sẽ bị vô hiệu và một số NullReferenceException sẽ bị ném.

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