2009-04-30 38 views
26

Tôi có mã sau để cho phép GUI phản hồi thay đổi trong bộ sưu tập.Làm cách nào để hủy đăng ký khỏi sự kiện sử dụng biểu thức lambda?

myObservableCollection.CollectionChanged += ((sender, e) => UpdateMyUI()); 

Đầu tiên, đây là cách hay để làm điều này?

Thứ hai: mã để hủy đăng ký sự kiện này là gì? Có giống nhau nhưng với - = (và sau đó là phương thức ẩn danh hoàn chỉnh một lần nữa)?

+0

? Sao chép: http://stackoverflow.com/questions/183367/unsubscribe-anonymous-method-in-c – Richard

+0

Xem [this] (http://stackoverflow.com/questions/183367/unsubscribe-anonymous-method -in-c). –

+0

Tôi đã không đặt biểu thức lambda của tôi trong một đại biểu (như trong liên kết của bạn), vì vậy tôi không có một tài liệu tham khảo để bỏ đăng ký. –

Trả lời

20

Nếu bạn cần hủy đăng ký khỏi sự kiện, bạn cần tham chiếu được phiên bản. Thật không may, điều đó có nghĩa là bạn không thể sử dụng cú pháp cụ thể đó.

+2

Nếu bằng "cú pháp cụ thể", bạn có nghĩa là tạo lambda và thêm trình xử lý vào một dòng, sau đó vâng. Các giải pháp đơn giản chỉ là lưu trữ một tham chiếu đến lambda. Thực sự, tôi nghĩ rằng OP nên xem xét việc sử dụng một phương pháp thông thường nếu anh ta cần phải tham khảo nó nhiều lần - nó cải thiện khả năng đọc, trong tâm trí của tôi ít nhất. – Noldorin

+0

Cảm ơn bạn đã xóa thông tin này. –

+0

@Noldorin Yep, đó là ý tôi là "cú pháp cụ thể" đó. Và tôi hoàn toàn đồng ý với bạn. –

35

Trước hết ... có một cách tốt để làm điều đó, hình thức nhỏ gọn, sạch sẽ và dễ đọc & hiểu ... thông báo trước là "Trừ khi bạn muốn hủy đăng ký".

Tôi tin rằng Jon Skeet được chỉ ra trước đó "đặc điểm kỹ thuật một cách rõ ràng không đảm bảo hành vi theo cách tương đương với các đại biểu được tạo bằng các phương thức ẩn danh".

Vì vậy, nếu bạn cần hủy đăng ký khỏi sự kiện sau này, tốt nhất bạn nên tạo một phiên bản ủy nhiệm để bạn có thể tham gia tham chiếu sau này.

var myDelegate = delegate(sender, e){UpdateMyUI()}; 

myObservableCollection.CollectionChanged += myDelegate; 

myObservableCollection.CollectionChanged -= myDelegate; 
+0

var myDelegate = delegate (người gửi, e) {UpdateMyUI()}; không biên dịch ... bạn cần phải chỉ định loại đại biểu. John Skeet sử dụng tác nhân Hành động trong ví dụ của mình nhưng chỉ có một đối số. Chúng ta nên sử dụng loại đại biểu nào trong ví dụ của bạn? –

+1

@RaduSimionescu: Giống như loại sự kiện, trong ví dụ này sẽ là 'NotifyCollectionChangedEventHandler' –

1

Đây là một cách ok để đi, trừ khi myObservableCollection sẽ sống lâu hơn 'này', trong trường hợp mà bạn có thể kết thúc với một rò rỉ bộ nhớ, như các đại biểu được tạo ra đằng sau hậu trường sẽ tiết kiệm một tham chiếu đến 'cái này' của bạn, cái sẽ giữ nó sống động. Nếu bạn liên tục tạo ra và 'phá hủy' bất cứ điều gì đang lắng nghe sự kiện, bạn sẽ thấy rằng chúng không được thu thập bởi người thu gom rác.

Nếu đây là sự cố, bạn có thể đi tuyến đường được đề xuất trong câu trả lời, bảo toàn tham chiếu đến trình xử lý mà bạn phải tạo trước.

Một giải pháp khác là sử dụng các tham chiếu yếu để tạo trình xử lý sự kiện cho phép người đăng ký được thu thập nếu không có các tham chiếu khác. Tôi đã khám phá giải pháp này trong this question and answer.

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