关闭子窗口再打开,提示未处理 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,但对象已经释放了。
这算垃圾回收的问题吗 --------------------编程问答-------------------- 问题是,垃圾回收的机制 不是引用为空了 才会回收吗。这样不矛盾吗
--------------------编程问答-------------------- --------------------编程问答--------------------
看来你是没搞懂Dispose方法的用途。举个例子吧,Dispose好比把房子里的东西都搬走,但是房子还在啊,只不过空间给出来了。
也就是说,你那个窗口占用的内部资源(可能)是释放了,但是窗口的引用还是存在的。(所以我说不怎么好回答)
另外你看看MSDN上关于非托管资源的回收例子就可以看出,调用了Dispose后都必须再指向null才行,这足够说明Dispose是不会指向null的。 --------------------编程问答--------------------
你好。是这个意思吗
每种类型都标识某些资源。
有些只占有内存,直接垃圾回收就行。
有些类型含有非托管资源,比如文件 数据库连接 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这种东西,一般都是为了手动快速释放(主要是非托管)资源弄的一种模式,你这个窗体涉及到了所谓的文件、数据库、网络操作等东西了吗,个人觉得没有必要搞得那么复杂。
--------------------编程问答--------------------
这个问题最后怎么解决呢,能在窗口关闭事件中使其隐藏而不是关闭吗
补充:.NET技术 , C#