private void button1_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
            f2.Dispose();
            MessageBox.Show(f2.s);
        }
在这段代码中f2已经dispose掉了,但是,messagebox仍然可以弹出f2.s的值。
按照道理,f2.s应该注销了才对啊?

解决方案 »

  1.   

    f2已经dispose掉了 但是GC还没工作呢
    你要真正的销毁要再加一句F2=null;
    当年写DELPHI都是FREEandNULL
      

  2.   

    Dispose并不是释放内存,析构函数才是。f2仍然指向那个对象,当然可以访问。
      

  3.   

       Application.OpenForms["Form2 "].Dispose();
      

  4.   

    Dispose并不是释放内存  LZ记住了
      

  5.   

    调用Dispose()不是释放对象的内存资源!
    调用Dispose()实际上是告诉GC这个对象可以回收了
    实际GC回收还有一系列的操作的,这都是.net内部封装的了
    ps: GC = 垃圾回收器编程的好习惯就是要做要规范!如变量命名到程序的流程要清晰做C#的不用过多在意内存的释放~
    以后你实践多了自会明白其中道理,经验才是最重要的 
      

  6.   

    GC是定时执行删除操作的,你的Dispose()只是告诉GC,窗体可以终结了,GC已经接收到通知,但是还没有进行下一步动作。
      

  7.   

    那么GC什么时候注销这些变量呢?
    我上面的程序会不会有问题,如果f2.s已经被GC回收注销掉了,但是我却去引用它。感觉这样,程序会有bug的?
      

  8.   

    GC 的调用是由 OS 负责,理想情况下是不由我们来操作的,但是如果需要,程序员也可以手工调用。
    如果你在 MssageBox 之前加一句 GC,应该会出错的,自己去试一下吧
      

  9.   

    private void button1_Click(object sender, EventArgs e)
            {
                Form2 f2 = new Form2();
                f2.Dispose();
                f2.ShowDialog();
                
                MessageBox.Show(f2.s);
            }这样就报错了;你那样是先SHOWDIALOG,F2已经被调用了;正调用中的是不能销毁资源;
      

  10.   

    总结:dispose只是在资源上加入删除标记,并没有真正删除资源。
    只有在CLR回收内存时,才真正回收掉资源。
      

  11.   


    你怎么就只是把眼睛盯在“删除资源”上呢?随便看看Form到底在dispose时做什么?protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            this.CalledOnLoad = false;
            this.CalledMakeVisible = false;
            this.CalledCreateControl = false;
            if (base.Properties.ContainsObject(PropAcceptButton))
            {
                base.Properties.SetObject(PropAcceptButton, null);
            }
            if (base.Properties.ContainsObject(PropCancelButton))
            {
                base.Properties.SetObject(PropCancelButton, null);
            }
            if (base.Properties.ContainsObject(PropDefaultButton))
            {
                base.Properties.SetObject(PropDefaultButton, null);
            }
            if (base.Properties.ContainsObject(PropActiveMdiChild))
            {
                base.Properties.SetObject(PropActiveMdiChild, null);
            }
            if (this.MdiWindowListStrip != null)
            {
                this.MdiWindowListStrip.Dispose();
                this.MdiWindowListStrip = null;
            }
            if (this.MdiControlStrip != null)
            {
                this.MdiControlStrip.Dispose();
                this.MdiControlStrip = null;
            }
            if (this.MainMenuStrip != null)
            {
                this.MainMenuStrip = null;
            }
            Form form = (Form) base.Properties.GetObject(PropOwner);
            if (form != null)
            {
                form.RemoveOwnedForm(this);
                base.Properties.SetObject(PropOwner, null);
            }
            Form[] formArray = (Form[]) base.Properties.GetObject(PropOwnedForms);
            for (int i = base.Properties.GetInteger(PropOwnedFormsCount) - 1; i >= 0; i--)
            {
                if (formArray[i] != null)
                {
                    formArray[i].Dispose();
                }
            }
            if (this.smallIcon != null)
            {
                this.smallIcon.Dispose();
                this.smallIcon = null;
            }
            this.ResetSecurityTip(false);
            base.Dispose(disposing);
            this.ctlClient = null;
            MainMenu menu = this.Menu;
            if ((menu != null) && (menu.ownerForm == this))
            {
                menu.Dispose();
                base.Properties.SetObject(PropMainMenu, null);
            }
            if (base.Properties.GetObject(PropCurMenu) != null)
            {
                base.Properties.SetObject(PropCurMenu, null);
            }
            this.MenuChanged(0, null);
            MainMenu menu2 = (MainMenu) base.Properties.GetObject(PropDummyMenu);
            if (menu2 != null)
            {
                menu2.Dispose();
                base.Properties.SetObject(PropDummyMenu, null);
            }
            MainMenu menu3 = (MainMenu) base.Properties.GetObject(PropMergedMenu);
            if (menu3 != null)
            {
                if ((menu3.ownerForm == this) || (menu3.form == null))
                {
                    menu3.Dispose();
                }
                base.Properties.SetObject(PropMergedMenu, null);
            }
        }
        else
        {
            base.Dispose(disposing);
        }
    }不要只把眼睛盯在什么内存空间上,不要像一些知道一些c++知识的.net程序员那样动不动就讨论内存空间问题。.net的程序的要点不在于空间,而在于丰富的功能。
      

  12.   

    楼主,呵呵,看看MSDN:
    这是MSDN的原文:
    调用完 Dispose 后,必须释放对 Component 的所有引用,这样垃圾回收器才能收回 Component 占用的内存。
      

  13.   

    实现 Finalize 和 Dispose 以清理非托管资源
    http://msdn.microsoft.com/zh-cn/library/b1yfkh5e(v=VS.80).aspx
      

  14.   

    f2.ShowDialog();
    f2.Dispose();
    你可以在f2.Dispose();处设置一个断点,在f2窗口关闭之前Dispose是不会执行的。
      

  15.   

    C#的Dispose();并不是真正的释放内存
    这个用不用其实没太大区别本身GC会自动回收没有指针的堆内存
    这个取决于你的内存是否够用。不够用时候就比较频繁的回收