C#使用委托时可能导致内存泄漏
用C#编写事件或委托时如果处理不好会造成内存泄漏,看下面代码:
public class DoA2EventArgs : EventArgs { } public class ClassA { public delegate void DoAEventHandler(object sender, EventArgs e); public event EventHandler<DoA2EventArgs> DoA2EventHandler; public DoAEventHandler DoAEvent; protected void OnDoA2Event(DoA2EventArgs args) { EventHandler<DoA2EventArgs> handler = DoA2EventHandler; if (handler != null) { handler(this, args); } } public void DoA() { if (DoAEvent != null) { DoAEvent(this, new EventArgs()); } } public void DoA2() { OnDoA2Event(new DoA2EventArgs()); } ~ClassA() { Console.WriteLine("Class A Finished!"); } } public class ClassB { ClassA a; public ClassB() { a = new ClassA(); a.DoAEvent = DoA; } public void DoA(object sender, EventArgs e) { } ~ClassB() { Console.WriteLine("Class B Finished!"); } }
如果我们做如下实现
ClassB b = new ClassB(); ClassA a = new ClassA(); a.DoAEvent = b.DoA; a.DoA2EventHandler += new EventHandler<DoA2EventArgs>(b.DoA2); b = null; GC.Collect();
这是我们会发现,虽然对象b已经被赋值为空,但对象并没有被GC回收掉。原因是a对象还存在,同时a对象的DoAEvent和 DoA2EventHandler 引用了b对象。
要将b回收掉我们可以做如下操作
一种方式是将a回收掉
a = null; b = null;
这样 b 就回收掉了。
如果不想把a回收掉则
a.DoAEvent = null; a.DoA2EventHandler -= b.DoA2;
还有一点要提一下的是
ClassB 类内部申明的 ClassA 对象,如果事件委托指向ClassB 对象本身,则不需要额外做操作,b = null; 时
ClassB 和 ClassA 实例都会自动回收。
来源:http://www.cnblogs.com/eaglet/archive/2009/01/07/1371060.html
加支付宝好友偷能量挖...