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


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

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







  • 相关阅读:
    四、git学习之——分支管理、解决冲突
    四、git学习之——远程仓库
    异常
    内部类
    接口
    Java三大特性之多态
    抽象类、抽象方法、final、Object类
    Java三大特性之继承
    Java三大特性之封装
    代码块、Package、Import
  • 原文地址:https://www.cnblogs.com/eaglet/p/1371060.html
Copyright © 2020-2023  润新知