无线事件是否有内存泄漏?

Pri*_*aka 6 c#

如果是,是否有办法在全局范围内为所有有线事件取消连线

编辑:比如说.我有对象,每个标记有一个事件,比如orm.NatureChanged += Nature_Changed;我在创建每个orm实例时标记这些事件.如果我没有通过orm.NatureChanged -= Nature_Changed;它会导致内存泄漏的方式解开?

Ada*_*son 6

无论你问什么,你问题的技术答案都是"不".从技术上讲,除非您发现CLR中存在错误,否则管理对象不存在真正的"内存泄漏"(这是使它们成为好事的重要部分).为了回答我认为你实际上在问的问题,听起来好像你问的是两件事之一:

  1. 对于没有附加任何委托的事件,是否需要执行某些操作?
  2. 事件是否可以防止垃圾收集器清理对象?

第一个问题的答案就是"不".继续前进,没有什么可看的.

第二部分的答案已在SO和网络的其他方面详细讨论过.简短版本是附加事件处理程序意味着GC将事件触发实例视为"可达"目标实例.这可能导致对象在内存中保留的时间超过预期,因为这种可访问性对于用户(开发人员)来说有点透明,因为构造委托的方式.

换句话说,我说有两个对象:Producer和Consumer.生产者触发消费者......消费的事件.

public class Producer
{
    public event EventHandler OmgIDidSomething;
}

public class Consumer
{
    public void AttachTo(Producer producer)
    {
        producer.OmgIDidSomething += new EventHandler(producer_OmgIDidSomething);
    }

    private void producer_OmgIDidSomething(object sender, EventArgs e)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,任何实例Consumer,其中AttachTo被称为仍将可达至于GC关注到的实例Producer,它连接到是符合回收,因为执行后面的委托OmgIDidSomething事件有实例的引用Consumer是它对应于.


kem*_*002 5

不,因为当您取消事件时,连接到事件的委托(它是一个对象)不再生根,并且在GC认为适合时将收集它.这假设当然事件委托没有附加到多个处理程序,在这种情况下,它将不会被收集,直到它从所有事件中取消连接.

  • 我想你可以想出一些手动的方法来跟踪哪个事件被连线到哪里,但这会变得很麻烦,你真的不会从中获得太多.你可能会浪费更多的内存来跟踪事件来展开它而不是让它成为现实并让gc在需要时处理它. (2认同)