我一直在阅读有关内存管理的内容,并且在一个项目中遇到过这样的情况,无论是这本书还是谷歌都没有给出确切的答案。我已经知道委托是管理对象,事件是委托实例。话虽如此,一旦应用程序结束,委托实例将从内存中删除。
我无法弄清楚的是如何确保在我的类被释放时(显式地或通过 GC)外部代码已释放所有事件引用。例如,类A
公开一个事件,类使用B
它。类B
调用 Dispose 类A
而不释放对委托的引用。当然,我们不能从 Dispose 方法本身抛出错误。
以下是一个具有委托的类和另一个使用它的类。
public class ClassB
{
private ClassA A { get; set; }
public ClassB()
{
this.A = new ClassA();
this.A.OnProcessed += new ClassA.DelegateProcessed(this.ClassA_Processed);
}
public void Process()
{
this.A.Process();
}
public void ClassA_Processed (ClassA sender, EventArgs e)
{
// Do something.
// Code written by another developer does not free up events before calling Dispose.
this.A.Dispose();
this.A = null;
}
}
public class ClassA: IDisposable
{
public delegate void DelegateProcessed (A sender, EventArgs e);
public event DelegateProcessed OnProcessed = null;
~ClassA() { this.Dispose(false); }
public void Dispose ()
{
this.Dispose(true);
System.GC.SuppressFinalize(this);
}
private void Dispose (bool disposing)
{
if (!this.Disposed)
{
if (disposing)
{
// Dispose managed resources here.
// Is it possible / advisable to dispose of delegates / events here?
// Will this adversely affect the consumer class?
this.OnProcessed -= new ClassA.DelegateProcessed(this.ClassA_Processed);
}
}
this.Disposed = true;
}
public void Process () { this.OnProcessed(this, new EventArgs()); }
public void ClassA_Processed (ClassA sender, EventArgs e) { }
}
关键是要确保无论开发人员对 ClassB 做什么,ClassA 都有资格进行垃圾收集。关键是即使消费者粗心,也要尽量减少 ClassA 在内存中花费的时间。
更新:从答案中可以清楚地看出,事件不必从 ClassA 中明确删除。至于主要问题,弱引用似乎是下面回答的方法。目标是最小化 ClassA 在内存中的停留时间。如果我忽略了任何事情,请告诉我。