C# 如何取消订阅使用 lambda 表达式的事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/805829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:56:38  来源:igfitidea点击:

How to unsubscribe from an event which uses a lambda expression?

c#.netc#-3.0event-handlinglambda

提问by Gerrie Schenck

I have the following code to let the GUI respond to a change in the collection.

我有以下代码让 GUI 响应集合中的更改。

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

First of all is this a good way to do this?

首先,这是一个很好的方法吗?

Second: what's the code to unsubscribe from this event? Is it the same but with -= (and then the complete anonymous method again)?

第二:取消订阅此事件的代码是什么?它是一样的,但使用 -= (然后又是完整的匿名方法)?

采纳答案by J. Steen

If you need to unsubscribe from an event, you need an instanced reference. Unfortunately, that means you can't use that particular syntax.

如果需要取消订阅事件,则需要实例化引用。不幸的是,这意味着您不能使用该特定语法。

回答by Eoin Campbell

First of all... yes its a good way of doing it, it's clean, small form and easy to read & understand... the caveat of course is "Unless you later want to unsubscribe".

首先......是的,这是一种很好的方式,它干净、小巧且易于阅读和理解......当然要注意的是“除非你以后想取消订阅”。

I believe Jon Skeetpointed out before that "the specification explicitly doesn't guarantee the behaviour either way when it comes to equivalence of delegates created with anonymous methods."

我相信Jon Skeet之前指出,“当涉及到使用匿名方法创建的委托的等效性时,规范明确不保证任何一种行为。”

So if you need to unsubscribe from the event at a later time, you'd be best to actually create a delegate instance so you can hang onto the reference for later.

因此,如果您稍后需要取消订阅该事件,您最好实际创建一个委托实例,以便您可以稍后保留引用。

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

myObservableCollection.CollectionChanged += myDelegate;

myObservableCollection.CollectionChanged -= myDelegate;

回答by Benjol

It's an ok way to go, unless myObservableCollection is going to live longer than 'this', in which case you could end up with a memory leak, as the delegate which is created behind the scenes will conserve a reference to your 'this', which will keep it alive. If you are repeatedly creating and 'destroying' whatever is listening to the event, you will find that they aren't being collected by the garbage collector.

这是一个不错的方法,除非 myObservableCollection 的存活时间比“this”长,在这种情况下,您最终可能会出现内存泄漏,因为在幕后创建的委托将保存对您的“this”的引用,这将使它保持活力。如果您反复创建和“销毁”正在侦听事件的任何内容,您会发现垃圾收集器并未收集它们。

If this is a problem, you can go the route suggested in the answers, conserving a reference to the handler, which you must create first.

如果这是一个问题,您可以选择答案中建议的路线,保留对处理程序的引用,您必须先创建该引用。

Another solution is to use weak references to create an event handler which will allow the subscriber to be collected if there are not other references. I've explored this solution in this question and answer.

另一种解决方案是使用弱引用来创建一个事件处理程序,如果没有其他引用,它将允许收集订阅者。我已经在这个问答中探索了这个解决方案。