Dispose close null showdialog

来源:互联网 发布:现在淘宝发空包会查吗 编辑:程序博客网 时间:2024/05/21 18:50

    at first ,i  have a reference the others' article:

 这就是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,这个已经反复说过多次了)。真正是实现的时候,可能还要考虑到多线程等诸多问题。

         now ,i do a test myself

namespace TestFrmDispose
{
    public partial class MainFrm : Form
    {
        public MainFrm()
        {
            InitializeComponent();
        }
        SubWindow myWindow;
        private void MainFrm_Load(object sender, EventArgs e)
        {
            myWindow = new SubWindow();
            if (myWindow.ShowDialog(this) == DialogResult.OK)
            {
              
            }
            else
            {
           
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            if (myWindow == null)
            {
                this.richTextBox1.AppendText("receive DialogResult and the window is Closed");
            }
            else
            {
                this.richTextBox1.AppendText("receive DialogResult and the window has exists");
                myWindow.Visible = true;//this word is used to test whether the window is hited;//the key is right;
                myWindow.Text = "123";
            }
        }

    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TestFrmDispose
{
    public partial class SubWindow : Form
    {
        public SubWindow()
        {
            InitializeComponent();
        }

        private void btnSure_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
        }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TestFrmDispose
{
    public partial class SubWindow : Form
    {
        public SubWindow()
        {
            InitializeComponent();
        }

        private void btnSure_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
        }
    }
}

原创粉丝点击