C# 事件处理程序会阻止垃圾收集的发生吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/298261/
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-03 22:09:50  来源:igfitidea点击:

Do event handlers stop garbage collection from occurring?

c#.netevent-handlinggarbage-collection

提问by Mark Ingram

If I have the following code:

如果我有以下代码:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

Will pClass be garbage collected? Or will it hang around still firing its events whenever they occur? Will I need to do the following in order to allow garbage collection?

pClass 会被垃圾收集吗?或者它会在事件发生时仍然继续触发它的事件吗?我是否需要执行以下操作才能允许垃圾收集?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;

采纳答案by Marc Gravell

For the specific question "Will pClass be garbage collected": the event subscription has no effect on the collection of pClass (as the publisher).

对于具体问题“Will pClass beGC”:事件订阅对pClass的收集没有影响(作为发布者)。

For GC in general (in particular, the target): it depends whether MyFunction is static or instance-based.

对于一般的 GC(特别是目标):这取决于 MyFunction 是静态的还是基于实例的。

A delegate (such as an event subscription) to an instance method includes a reference to the instance. So yes, an event subscription will prevent GC. However, as soon as the object publishing the event (pClass above) is eligible for collection, this ceases to be a problem.

对实例方法的委托(例如事件订阅)包括对实例的引用。所以是的,事件订阅将阻止 GC。然而,一旦发布事件的对象(上面的 pClass)符合收集条件,这就不成问题了。

Note that this is one-way; i.e. if we have:

请注意,这是单向的;即如果我们有:

publisher.SomeEvent += target.SomeHandler;

then "publisher" will keep "target" alive, but "target" will not keep "publisher" alive.

那么“publisher”将使“target”保持活动状态,但“target”不会使“publisher”保持活动状态。

So no: if pClass is going to be collected anyway, there is no need to unsubscribe the listeners. However, if pClass was long-lived (longer than the instance with MyFunction), then pClass could keep that instance alive, so it wouldbe necessary to unsubscribe if you want the target to be collected.

所以不:如果无论如何都要收集 pClass,则无需取消订阅侦听器。但是,如果pClass是长寿命(比MyFunction的实例更长),然后pClass可以保持该实例活着,所以需要退订,如果你想收集的对象。

Static events, however, for this reason, are very dangerous when used with instance-based handlers.

然而,由于这个原因,静态事件在与基于实例的处理程序一起使用时非常危险。

回答by Tor Haugen

Yes, pClass will be garbage collected. The event subscription does not imply that any reference exists to pClass.

是的,pClass 将被垃圾收集。事件订阅并不意味着存在对 pClass 的任何引用。

An so no, you will not have to detach the handler in order for pClass to be garbage collected.

所以不,您不必分离处理程序以使 pClass 被垃圾收集。

回答by lvaneenoo

The moment a piece of memory is no longer referenced it becomes a candidate for garbage collection. When the instance of your class goes out of scope, it is no longer referenced by your program. It is no longer used and therefore can be safely collected.

当一块内存不再被引用时,它就成为垃圾收集的候选对象。当您的类的实例超出范围时,您的程序将不再引用它。它不再使用,因此可以安全地收集。

If you are not sure wether something will get collected ask yourself the following question: does there still exist a reference to it? The event handlers are referenced by the object instance, not the other way around.

如果您不确定是否会收集某些东西,请问自己以下问题:是否仍然存在对它的引用?事件处理程序由对象实例引用,而不是相反。

回答by Arav

pClasswill be garbage collected. However, if the code snippet above is inside another class, the instance of that class might not be cleared if you do not set pClassto null.

pClass将被垃圾收集。但是,如果上面的代码片段在另一个类中,如果不设置pClass为,则该类的实例可能不会被清除null