2011-11-03 22 views
5

Cân nhắc tình huống mà bạn muốn đăng ký một sự kiện cho một sự kiện và chỉ một thông báo. Khi thông báo đầu tiên hạ cánh, bạn hủy đăng ký khỏi tất cả các sự kiện trong tương lai. Mô hình sau sẽ trình bày bất kỳ vấn đề bộ nhớ nào? Nó hoạt động, nhưng tôi đã không chắc chắn nếu đóng cửa tự tham khảo có thể giữ những thứ xung quanh trong bộ nhớ lâu hơn mong muốn.Mẫu sau có thể hủy đăng ký tự của bạn khỏi sự kiện qua việc đóng cửa có gây ra bất kỳ sự cố nào không?

public class Entity 
{ 
    public event EventHandler NotifyEvent; 
} 

// And then, elsewhere, for a listen-once handler, we might do this: 
Entity entity = new Entity(); 
Action<object, EventArgs> listener = null; 
listener = (sender, args) => 
{ 
    // do something interesting 
    // unsubscribe, so we only get 1 event notification 
    entity.NotifyEvent -= new EventHandler(listener); 
}; 
entity.NotifyEvent += new EventHandler(listener); 

Lưu ý rằng bạn phải khai báo 'người nghe' và gán giá trị (null). Nếu không trình biên dịch than phiền về 'Sử dụng biến cục bộ chưa được gán listener'

+0

Bạn có thể làm cho mã của mình trở nên biểu cảm hơn bằng cách đặt một phần mã của bạn bắt đầu bằng 'Action listener = null;' trong dấu ngoặc nhọn. Nhưng tôi không chắc chắn nếu điều này sẽ làm cho cuộc sống dễ dàng hơn cho các nhà sưu tập rác: sau khi tất cả, bạn anyway không sử dụng biến của bạn nữa! – Vlad

Trả lời

6

Không có gì sai với mẫu này. Đó là cùng một mẫu mà tôi và nhiều người khác sử dụng để gán và loại bỏ một biểu thức lambda cho một trình xử lý sự kiện.

+0

Câu hỏi về mã này: Người gửi có thể được sử dụng để thực hiện hủy đăng ký không? Một cái gì đó như (người gửi dưới dạng thực thể) .NotifyEvent - = new EventHandler (người nghe) cũng bên trong biểu thức lamba, hoặc nó có thể là một số vấn đề phụ? –

+0

@RickyAH có thể. Nó sẽ làm việc cho một số loại mặc dù tôi sẽ không khuyên bạn nên làm nó. Tôi thường rất thận trọng khi tin tưởng phần 'người gửi' của mẫu sự kiện. Đôi khi nó hữu ích nhưng tôi cho rằng nó là một giá trị không đáng tin cậy – JaredPar

+0

cảm ơn phản hồi. –

4

Trong khi tôi nghĩ rằng mẫu chung là tốt, tôi sẽ không đi qua Action<object, EventArgs>. Tôi muốn sử dụng:

EventHandler listener = null; 
listener = (sender, args) => 
{ 
    // do something interesting 
    // unsubscribe, so we only get 1 event notification 
    entity.NotifyEvent -= listener; 
}; 
entity.NotifyEvent += listener; 
+0

Cảm ơn mẹo. Tôi thực sự thường sử dụng đại biểu sự kiện tùy chỉnh anyway, nhưng đối với ví dụ tôi chỉ sử dụng EventHandler là đại biểu sự kiện, vì nhiều người nhận ra nó. Hoàn toàn cách nhau trên Action mặc dù vậy, cảm ơn. (sẽ để lại ví dụ ít lý tưởng của tôi tại chỗ để cung cấp ngữ cảnh câu trả lời của bạn) – Matt

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