当前位置:编程学习 > C#/ASP.NET >>

关闭子窗口再打开,提示未处理 ObjectDisposedException异常

如果不用MDI来实现一个主窗体打开多个子窗体时,

从一个窗体(主窗体)打开一个(only one) 另外一个的窗体(子窗体)的实现

 

父窗体:MainForm

 

public partial class MainForm:Form

{

    ............

 

    private void menuItem1_Load(object sender,EventArgs e)     

     {

        ChildForm child1=ChildForm.Create();

        child1.show();

        child1.Focus();

     }

   

    //......

}

 

子窗体:ChildForm

 

public partial class ChildForm:Form

{

     .....

 

     static ChildForm child;

     

     Public static ChildForm Create()

      {

         if(child==null)

            child=new ChildForm();

          return Child; 

      }

     ......

}

 

F5运行后,的确实现了上面提到的功能。然而,把子窗体关闭后,想再次打开该子窗体时,单击菜单项,会出现异常:ObjectDisposedException was unhandled.

 

        这是为什么呢??

原因:关闭子窗体时,执行了Dispose,但instance未置为null.修改closing事件,置为null就可以了。

我想问的是

这根垃圾回收有关系吗,是已经回收 但没将引用置为null是把 --------------------编程问答-------------------- 已经被disposed所有的引用都被指空,必须要重新实例化它才可以再引用 --------------------编程问答-------------------- 不知道怎么回答是好,总之你记住:所有对象的Dispose方法都不会使对象的变量置为null,那个仅仅是清理对象内部的垃圾回收,和对象本身的引用无关。 --------------------编程问答-------------------- 问题背景是实现mdi窗口,对于每个子窗口,顶多有一个实例。也就是一个子窗口已经打开了,再次点击打开时,不再创建新实例,上面用单态实现。但是这样有一个问题,就是关闭子窗口,再次打开时,会提示未处理 ObjectDisposedException异常。因为子窗口引用不会null,但对象已经释放了。
这算垃圾回收的问题吗 --------------------编程问答-------------------- 问题是,垃圾回收的机制 不是引用为空了 才会回收吗。这样不矛盾吗

引用 2 楼 qldsrx 的回复:
不知道怎么回答是好,总之你记住:所有对象的Dispose方法都不会使对象的变量置为null,那个仅仅是清理对象内部的垃圾回收,和对象本身的引用无关。
--------------------编程问答-------------------- --------------------编程问答--------------------
引用 4 楼 gsxrb521 的回复:
问题是,垃圾回收的机制 不是引用为空了 才会回收吗。这样不矛盾吗


引用 2 楼 qldsrx 的回复:
不知道怎么回答是好,总之你记住:所有对象的Dispose方法都不会使对象的变量置为null,那个仅仅是清理对象内部的垃圾回收,和对象本身的引用无关。

看来你是没搞懂Dispose方法的用途。举个例子吧,Dispose好比把房子里的东西都搬走,但是房子还在啊,只不过空间给出来了。
也就是说,你那个窗口占用的内部资源(可能)是释放了,但是窗口的引用还是存在的。(所以我说不怎么好回答)
另外你看看MSDN上关于非托管资源的回收例子就可以看出,调用了Dispose后都必须再指向null才行,这足够说明Dispose是不会指向null的。 --------------------编程问答--------------------
引用 6 楼 qldsrx 的回复:
引用 4 楼 gsxrb521 的回复:
问题是,垃圾回收的机制 不是引用为空了 才会回收吗。这样不矛盾吗


引用 2 楼 qldsrx 的回复:
不知道怎么回答是好,总之你记住:所有对象的Dispose方法都不会使对象的变量置为null,那个仅仅是清理对象内部的垃圾回收,和对象本身的引用无关。

看来你是没搞懂Dispose方法的用途。举个例子吧,Dispose好比把房子里的东西……
  

你好。是这个意思吗

每种类型都标识某些资源。
有些只占有内存,直接垃圾回收就行。
有些类型含有非托管资源,比如文件 数据库连接 socket,这些类型需要先释放非托管资源,再释放内存。finalize和dispose都是用来释放非托管资源的。调用了dispose,但对象可能还在,是把?
--------------------编程问答--------------------  frmSettings fset = new frmSettings();
 private void btnBack_Click(object sender, EventArgs e)
        {

            
            fset.Show();

        }
--------------------编程问答--------------------  frmSettings fset = new frmSettings();
 private void btnBack_Click(object sender, EventArgs e)
        {

            
            fset.Show();

        }
--------------------编程问答-------------------- 你这个既然是MDI窗体了,为了只出现一个窗体,你根本没有必要弄什么单例,直接child1.ShowDialog()就可以了。
然后就是主动去实现IDispose这种东西,一般都是为了手动快速释放(主要是非托管)资源弄的一种模式,你这个窗体涉及到了所谓的文件、数据库、网络操作等东西了吗,个人觉得没有必要搞得那么复杂。
--------------------编程问答--------------------
引用 3 楼 gsxrb521 的回复:
问题背景是实现mdi窗口,对于每个子窗口,顶多有一个实例。也就是一个子窗口已经打开了,再次点击打开时,不再创建新实例,上面用单态实现。但是这样有一个问题,就是关闭子窗口,再次打开时,会提示未处理 ObjectDisposedException异常。因为子窗口引用不会null,但对象已经释放了。
这算垃圾回收的问题吗


这个问题最后怎么解决呢,能在窗口关闭事件中使其隐藏而不是关闭吗
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,