![](/img/trans.png)
[英]How to fix memory leak when passing object from C# COM library to a C++ application
[英]C# - Memory leak when passing an event as parameter to a subclass
在过去的几天里,我一直跟踪应用程序中的内存泄漏。 我知道编写此代码的开发人员的想法,但是我并不是真的知道为什么会发生泄漏。 想法是要有一个包含事件的类。 该类将实例化另一个类,该类将在Init方法中向事件添加事件处理程序,并将其删除,并调用Stop方法。 问题在于,该事件没有从主类中删除,并且InvocationTargetList越来越大。 这是一个示例源代码,它显示了该问题:
public class SampleEventArgs
{
public SampleEventArgs(string s) { Text = s; }
public String Text { get; private set; }
}
public class MainClass
{
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
public event SampleEventHandler SampleEvent;
public SubClass m_SubClass = new SubClass();
public MainClass()
{
for (int i = 0; i < 10000; i++)
{
m_SubClass.Init(ref SampleEvent);
m_SubClass.Close();
}
if (SampleEvent != null)
Console.WriteLine("SampleEvent InvocationTargetList length: {0}", SampleEvent.GetInvocationList().Length);
Console.ReadKey();
}
}
public class SubClass
{
public event MemoryLeakTest.MainClass.SampleEventHandler m_Subscription;
public void Init(ref MainClass.SampleEventHandler SampleEvent)
{
SampleEvent += NewEvent;
m_Subscription = SampleEvent;
}
public void Close()
{
m_Subscription -= NewEvent;
}
public void NewEvent(object sender, SampleEventArgs e)
{
}
}
好了,我已经通过将类传递给Init和Stop方法来解决此问题,并且还实现了IDisposeable模式,但我不确定100%为什么上面的代码会导致内存泄漏。 造成这种情况的原因是,因为将SampleEvent分配给m_Suscription会创建该事件的副本,因此该事件将仅从Stop方法中的m_Subscription变量中删除? 有任何想法吗?
好了,我们已经知道委托是不可变的,这就是为什么您使用ref
参数来订阅事件。
现在仔细看一下这个方法
public void Close()
{
m_Subscription -= NewEvent;
}
实际上,您是从副本退订,而不是从MainClass
原始委托MainClass
。 换句话说,您将只重新分配子类中的字段,而不是重新分配主类中的字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.