C#在父窗口中调用子窗口的过程:
1、 创建子窗口对象
2、 显示子窗口对象
 
笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm。在窗体中定义了子窗口对象,然后在菜单项点击事件中,加入了如下代码来创建和显示子窗口:
Private childFrm myChildFrm = null; //定义子窗口对象
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
{
myChildFrm = new ChildFrm();//创建子窗口对象
myChildFrm.Show();//显示子窗口
myChildFrm.Focus();//使子窗口获得焦点
}
当点击菜单中的OpenChild项时,创建了子窗口并显示在最前面。此时如果关闭子窗口再点击菜单打开,不会有问题。但是如果子窗口没有关闭的情况下,再次点击菜单中的OpenChild项,则会再创建一个子窗口。两个子窗口具有相同的内容,这不是我们所希望看到的。
 
为此,对菜单项点击事件做如下改进:
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
{
if(myChildFrm != null)
{
myChildFrm.Show();//显示子窗口
myChildFrm.Focus();//使子窗口获得焦点
}
else
{
myChildFrm = new ChildFrm();//创建子窗口对象
myChildFrm.Show();//显示子窗口
myChildFrm.Focus();//使子窗口获得焦点
}
}
这样修改的目的是:当子窗口对象存在时,直接显示子窗口。当子窗口不存在时,创建子窗口,然后再显示。
 
现在来检验效果:当第一次点击OpenChild菜单项时,创建子窗口并正确显示。不关闭子窗口的情况下再点击OpenChild菜单项,子窗口只显示了一个,说明按预期工作了。现在,我们关闭子窗口,再点击OpenChild菜单项,程序在运行到下面这个语句时出现“未处理ObjectDisposedException”异常。
if(myChildFrm != null)
{
myChildFrm.Show();//显示子窗口
}
错误信息:无法访问已释放的对象。对象名:“childFrm”。
 
这就让人奇怪了。如果子窗口没有被销毁,那它就应该能够正确显示。点击了关闭子窗口,显然应该子窗口已经销毁了,按理myChildFrm等于null,运行的时候应该直接运行else后面的语句块,为什么却进入了满足myChildFrm!=null的语句块呢?
 
其实,这个问题与C#的垃圾回收有关。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C#对象没有确定性毁坏。所以会出现子窗口对象已被销毁,但又不为null,故出现访问时产生“未处理ObjectDisposedException”异常(来自于“从小处看C#.net垃圾回收”一文)。
 
如何解决这个题,有人提出:应该应该彻底回收Child所占的资源。并提供了解决方法(请搜索“从小处看C#.net垃圾回收”查看相关情况)。
 
其实,现在我们需要解决的问题仅仅是:子窗口已经被销毁,但对象却不为null。只需要对你窗口中的菜单点击事件函数进行简单修改就可以了。
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
{
if(myChildFrm != null)
{
if(myChildFrm.IsDisposed)
myChildFrm = new ChildFrm();//如果已经销毁,则重新创建子窗口对象
myChildFrm.Show();
myChildFrm.Focus();
}
else
{
myChildFrm = new ChildFrm();
myChildFrm.Show();
myChildFrm.Focus();
}
}
前面这是按逻辑的方式进行思考的,显示子窗口和获得焦点两行是重复的,两个if语句也可以做一下简化。指定子窗口和父窗口的父子关系。最后的结果是这样:
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
{
if(myChildFrm == null || myChildFrm.IsDisposed)
{
myChildFrm = new ChildFrm();
}
myChild..MdiParent = this; //建立父子关系 myChildFrm.Show(); //显示子窗口
myChildFrm.Focus(); //子窗口获得焦点
}
这样,就能够如我们如愿般调用子窗口了。
 
转载自CSDN博客,ID:新城  url: https://blog.csdn.net/c61999/article/details/8153476

C# WinForm:无法访问已释放的对象的更多相关文章

  1. C# WinForm:无法访问已释放的对象

    C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象   笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中 ...

  2. C# Socket连接 无法访问已释放的对象

    在进行Socket长连接时,若服务器或客户端出现异常时,另外一端对Socket对话进行操作时,程序会出现无法访问已释放的对象的问题.例如客户端出现问题主动断开Socket时,当服务器操作Socket时 ...

  3. C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。

    一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...

  4. (转)C#在父窗口中调用子窗口的过程(无法访问已释放的对象)

    C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象   笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中 ...

  5. c# winFrom Close报错 System.ObjectDisposedException:“无法访问已释放的对象。

    System.ObjectDisposedException:“无法访问已释放的对象. ObjectDisposed_ObjectName_Name” 查了一下发现是 InitializeCompon ...

  6. Tooltip导致的无法访问已释放对象

    最近C#项目中遇到了一个无法访问已释放对象问题,经过反复测试,最终发现问题出在控件Tootip上,因为tootip内部有一个定时器,如果在窗口销毁时,鼠标移动到控件上恰好产生了一个tooltip,就会 ...

  7. C# “试图访问已释放的资源”

    WinCE项目 VS2008 项目现有一个公共静态类PublicItems,一个窗体模板FormModel,三个继承自模板的子窗体. 现在想要实现在其中一个子窗体中对所有子窗体上一个Label显示进行 ...

  8. socket对象放在一个datagridview的row的tag里面在拿出来 为什么是已释放

     socket对象放在一个datagridview的row的tag里面在拿出来 为什么是已释放 

  9. WdatePicker 没有权限 不能执行已释放 Script 的代码

    提示 拒绝访问 或 没有权限 或 ' Window.document 或 '$dp' 为空或不是对象 $dp.dd is undefined 之类的错误 SCRIPT70: 没有权限 WdatePic ...

随机推荐

  1. CSS盒模型深入理解

    前言 所有文档元素都生成一个矩形框,这称为元素框(element box),它描述了一个元素在文档布局中所占的空间大小.而且,每个框影响着其他元素框的位置和大小 宽高 宽度width被定义为从左内边界 ...

  2. [Android] Android 锁屏实现与总结 (一)

    实现锁屏的方式有多种(锁屏应用.悬浮窗.普通Activity伪造锁屏等等).但国内比较主流并且被广泛应用的Activity伪造锁屏方式. 实例演示图片如下: 系列文章链接如下: [Android] A ...

  3. Html一些特殊字符(Html语法字符)的一种表达方式

      空格 & & < < > > " " &qpos; '

  4. volative 与处理器的嗅探技术

    在<java并发编程的艺术>这本书中,关于volatile的内存原理本质的描述如下: 有volatile变量修饰共享变量在编译器编译后,后多出一个“lock” 来(lock前缀指令相当于一 ...

  5. windows 下 bat 计划任务删除保留时间内文件

    date  windows 打印时间戳  年:echo %date:~,% 月:echo %date:~,% 日:echo %date:~,% 星期:echo %date:~,% 小时:echo %t ...

  6. cpp智能指针

    weak_ptr<Cls1> wp1; { shared_ptr<Cls1> ptr1(new Cls1);//共享指针 wp1 = ptr1;//临时共享指针 std::co ...

  7. 分布式系列七: zookeeper简单用法

    zookeeper是分布式开源框架, 是Google Chubby的一个实现, 主要作为分布式系统的协调服务. Dobbo等框架使用了其功能. zookeeper特性 顺序一致性: 事务请求最终会严格 ...

  8. 简单对比git pull和git pull --rebase的使用

    使用下面的关系区别这两个操作:git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase 现在来看看git m ...

  9. Linux su切换用户后命令提示符变为bash-4.2$

    2018-9-30 19:31:41 星期日 今天遇到一个问题, 给gitlab配置webhook的时候, 一个目录总是不能正确执行git pull 命令, 无任何输出, 根据之前经验, 感觉是权限的 ...

  10. Django学习笔记(http协议与django安装)

    Django入门 HTTP协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器 ...