Dispose、Close、=null三者之间的区别

原创 2008年06月20日 14:13:00
 
上午想做个简单的单件设计模式(Singleton)的小例子,结果出现了一些意想不到的问题。我的本意是建立两个窗体类Form1和Form2,在Form2上放置一个名为Button1的按钮,单击Button1会调出Form1的窗口事例,并且保证再单击Button1的时候,不会再弹出第二个Form1实例,除非关掉Form1实例并重新单击Button1,总之,保证只能弹出一个Form1实例(当然不是用模态方式啦)。代码如下所示:
 
Form1类
       public class Form1
       {    
              private static Form1 frm;
              private Form1()//这个构造函数只允许类内调用,所以是私有的
              {
                     InitializeComponent();
              }
 
              public static Form1 CreateForm1()//该函数可带参数,自己想想如何实现
              {
                     if(frm == null)
                     {
                            frm = new Form1();
                            return frm;
                     }
                     else
                     {
                            return frm;
                     }
              }
       }
 
Form2类
              public class Form2
       {    
              ..... 
              private void button1_Click(object sender, System.EventArgs e)
              {
                     Form1 frm1 = Form1.CreateForm1();
                     frm1.Show();
              }
              .....
       }
于是问题出现了:我单击Form2窗体上的一个名为button1按钮要弹出Form1的窗口(函数如上),第一次可以弹出来,并且可以保证再单击button1时,不再弹出Form1的窗口,但是关闭Form1窗口实例后,再次单击button1按钮则出错,解释为无法访问名为“Form1”的已处置对象。这是什么原因?
经过细致的观察和向高手询问,终于搞清楚了问题的真相。这就是Dispose和null之间的区别。Dispose和Close是相同的,据说是因为有些类有Open的方法,所以为了对应才搞出了一个Close方法。Dispose()方法实际上是销毁了对象的实例,但是该对象变量仍然指向这块被销毁的内存地址上!而只要有所指向,它就绝不等于null!而若原来夫frm = new Form1();然后又frm = null;这意味着frm不再指向new出来的对象,他们之间的关系被“切断”了,frm成了一个没有指向的变量,但同时new出来的那个对象也占据着一块内存,它并没有被干掉!后来我又发现,窗体在执行Close()方法后会激发Closing事件,而使用dispose()方法则不会激发该事件。在singleton模式中,单例窗体的Closing事件里面,加入了“frm=null;”这么一句话,所以不要用dispose()关闭单例窗体,而要用Close()方法关闭。引申出来,所有拥有Close()方法的类,最好都用Close()方法关闭,而不要用Dispose()方法。
所以,上面的例子中,把frm1关掉后,它new出来的那个对象所占用的地址被dispose掉了,但是变量frm1仍然指向这块被dispose掉的地址!所以它也就不等于null!所以当再次单击Button1的时候,直接进入了else部分,导致了错误。那怎么解决呢?这么办,在Form1的Closed事件中将frm1设置成null,就可以了。因为关闭窗体,执行dispose的时候,窗体内的其他代码并不停止,直到执行完毕,所以,可以将frm1设置成null,完全没有问题。
这里还有另外一个问题。假如一个对象(自定义的类的实例)没有dispose掉,就把它设置成null,那这块内存怎么办呢?垃圾回收机制会自动收拾它的。但是垃圾回收机制,不能保证何时去回收它,所以你也不知道它到底啥时候能回收掉,这样可能影响系统的效率。解决方法是,使该类继承IDisposable接口,然后实现他的Dispose()方法。函数内写GC.SuppressFinalize(this);这样,如果手动调用dispose()方法,GC就不会通过析构函数再次销毁对象了。尤其当这个对象作为局部变量的时候,这样做是很有必要的。可以将dispose()写入finally{}语句中,更好的方法是使用using关键字把代码装入{}中。例如:
Using(Class1 cls1 = new Class())
{。。。。}
Using里的参数必须是实现了dispose方法的对象。当程序运行出{}时,自动销毁cls1(但是cls1!=null,这个已经反复说过多次了)。真正是实现的时候,可能还要考虑到多线程等诸多问题。

改善C#程序的建议5:引用类型赋值为null与加速垃圾回收

【转载】改善C#程序的建议5:引用类型赋值为null与加速垃圾回收 在标准的Dispose模式中(见前一篇博客“C#中标准Dispose模式的实现”),提到了需要及时释放资源,却并没有进一步...
  • dkss0309
  • dkss0309
  • 2016年11月12日 16:09
  • 500

dispose 和 null区别

GameObject obj = new GameObject(); obj.dispose() 和 obj = null 的区别是: dispose的功能是将obj对象销毁, 而obj= nul...
  • wangxiong_zh
  • wangxiong_zh
  • 2017年06月25日 23:07
  • 94

深入解析Close()和Dispose()的区别

很多人都认为Close()方法内部会调用Dispose()方法,所以并没有本质的区别!实际上这个看法不是很准确,对有 些类来说,的确Close()和Dispose()没有本质区别,但是对有些类来...
  • daihongshu
  • daihongshu
  • 2014年05月12日 10:46
  • 1655

close和dispose的区别

close和dispose区别
  • zsx157326
  • zsx157326
  • 2016年05月05日 19:26
  • 763

dispose()与close()的区别 及pooling连接池相关

Dispose了,就必须再Create一次 而Close()后,还可以再Open(), 而Dispose后,对象都不存在了,就不能Open()了 Dispose是对于对象自身而言的,Close...
  • gtosky4u
  • gtosky4u
  • 2015年10月08日 11:30
  • 1641

C#中Dispose、析构函数、close的区别

析构函数不能显示调用,而对于Dispose、close方法来说,都需要进行显示调用才能被执行。 一、Close与Dispose这两种方法的区别 调用完了对象的Close方法后,此对象有可能...
  • yeqi3000
  • yeqi3000
  • 2016年11月10日 09:56
  • 2958

C#中Dispose和Close的区别!

当我们开发C#代码的时候,经常碰到一个问题,有些class提供Close(),有些class提供Dispose(),那么Dispose和Close到底有什么区别? 首先,Dispose和Clos...
  • yulongguiziyao
  • yulongguiziyao
  • 2014年05月08日 10:24
  • 425

C#中Dispose和Close的区别

当我们开发C#代码的时候,经常碰到一个问题,有些class提供Close(),有些class提供Dispose(),那么Dispose和Close到底有什么区别?首先,Dispose和Close基本上...
  • AkashaicRecorder
  • AkashaicRecorder
  • 2015年11月10日 20:36
  • 253

C# 资源释放及dispose、close方法

需要明确一下C#程序(或者说.NET)中的资源。简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象; 非...
  • u012252959
  • u012252959
  • 2015年08月24日 11:14
  • 2960

Finalize、Dispose、Close 的区别与使用

 如果您在搜索引擎中搜索类似于“Finalize Dispose Close 区别”的短语,将会得到一大堆搜索结果,然而很多文章讲得都比较迷糊,甚至其中包含有错误,这里对这几个方法作一个介绍。 ...
  • Lyncai
  • Lyncai
  • 2014年11月09日 13:50
  • 491
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Dispose、Close、=null三者之间的区别
举报原因:
原因补充:

(最多只允许输入30个字)