2009-07-15 30 views
5

Tôi đã nhìn thấy loại mã này một số nơi:C#: Khởi tạo một event handler với một hình nộm

public event SomeEventHandler SomeEvent = (s, e) => { }; 

Có phải đó là một cách khuyến khích làm việc? Nó giải quyết những gì, và nó có tác dụng phụ đáng chú ý nào không? Tôi vẫn phải thực hiện kiểm tra không? Hay đó chính là điều tôi không phải làm nữa? Bộ sưu tập rác sẽ vẫn hoạt động đúng không?


Ví dụ:

private PropertyChangedEventHandler propertyChanged; 
private readonly object propertyChangedLock = new object(); 
public event PropertyChangedEventHandler PropertyChanged 
{ 
    add 
    { 
     lock (propertyChangedLock) 
      propertyChanged += value; 
    } 
    remove 
    { 
     lock (propertyChanged) 
      propertyChanged -= value; 
    } 
} 
protected void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler; 
    lock (propertyChangedLock) 
     handler = propertyChanged; 

    if (handler != null) 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
} 

Tôi có thể thay đổi dòng đầu tiên vào này:

private PropertyChangedEventHandler propertyChanged = (s, e) => { }; 

Và sau đó bỏ qua null-kiểm tra trong phương pháp OnPropertyChanged? Và nếu sau đó tôi bỏ qua kiểm tra null, tôi có thể bỏ qua khóa không? Nếu như vậy sẽ cho tôi điều này:

protected void OnPropertyChanged(string propertyName) 
{ 
    propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
} 

Điều đó có an toàn khi thực hiện việc khởi tạo tài khoản không? Hoặc có một số tác dụng phụ mà tôi đã bỏ lỡ?

+2

Bài viết của tôi về chủ đề: http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx –

+0

Bài viết hay! Nói cách khác, việc loại bỏ kiểm tra null sẽ là thread-safe trong trường hợp này. Nhưng người đăng ký cần có trình xử lý thông minh không bị hỏng. Tôi có đúng không? – Svish

Trả lời

7

Mặc dù bạn không cần thực hiện kiểm tra tính rỗng, nếu bạn thực sự muốn thử sự kiện thread-an toàn, bạn vẫn cần phải lấy nó trong một khóa:

protected void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler; 
    lock (propertyChangedLock) 
    { 
     handler = propertyChanged; 
    } 
    handler(this, new PropertyChangedEventArgs(propertyName)); 
} 

nếu không, bạn có thể không được lấy giá trị gần đây nhất - nếu xử lý sự kiện đang được thêm vào trong một chủ đề khác nhau, bạn có thể về mặt lý thuyết nâng cao sự kiện mãi mãi mà không bao giờ gọi những người xử lý mới. Trong thực tế, tôi tin rằng bạn gần như luôn luôn nhận được đi mà không có khóa, nhưng trong điều kiện mô hình bộ nhớ, bạn nên có một số loại hàng rào.

Cá nhân tôi khuyên bạn không nên thử để đảm bảo sự kiện an toàn cho chủ đề.

+0

Vì vậy, bạn chỉ muốn bỏ qua tất cả các công cụ an toàn cho chủ đề? – Svish

+0

Có. Nhận người gọi đăng ký theo chủ đề thích hợp. –

+0

Bạn sẽ làm điều đó như thế nào? – Svish

0

Bạn có thể xem nó như là việc triển khai NULL Object pattern.

Nó giúp làm cho mã của bạn dễ đọc hơn, vì bạn không cần thực hiện kiểm tra giá trị NULL.

Các khóa trong logic thêm/xóa của bạn sẽ phải giữ nguyên nếu cần thiết ngay bây giờ. Họ không có gì để làm với nó. Chúng được sử dụng để tránh các điều kiện chủng tộc (nhưng tôi không biết liệu chúng có cần thiết trong hoàn cảnh của bạn hay không)

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