现在的位置: 首页 > 综合 > 正文

事件委托使用时内存泄漏的问题

2013年10月30日 ⁄ 综合 ⁄ 共 1919字 ⁄ 字号 评论关闭

事件委托使用时内存泄漏的问题

   用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 实例都会自动回收。

抱歉!评论已关闭.