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();  //子窗口获得焦点
}
 
 
 
这样,就能够如我们如愿般调用子窗口了。
 
 

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. Webpack之“多页面开发”最佳实战

    前言:相信之前看过这篇文章,前端构建工具之“Webpack”的朋友,对于Webpack有了一定的了解.那么今天就跟大家分享下:如何利用webpack,来进行多页面项目实战开发. 一.项目初始化安装 1 ...

  2. Python函数-any()

    any(iterable) 作用: 如果iterable的任何元素不为0.''.False,all(iterable)返回True.如果iterable为空,返回False. 函数等价于: def a ...

  3. 为什么很多公司招聘前端开发要求有 Linux / Unix 下的开发经验?

    知乎: http://www.zhihu.com/question/19666395

  4. ASP.NET网站性能提升的几个方法

    1. HTTP 压缩 HTTP 压缩通常用于压缩从服务端返回的页面内容.它压缩HTTP请求和响应,这个会是巨大的性能提升.我的项目是基于Window Server 2003开发的,可以参考这篇文章. ...

  5. 减小SSN影响

    单板级SSN 从单板级来看,芯片中多个逻辑门同时翻转时,将从单板电源和地平面瞬间汲取较大的电流.任何电源分配系统都存在着阻抗,特别是感抗,导致在短时间内电压调整模块来不及供应这些电流,从而在单板和电源 ...

  6. 蓝桥杯 历届试题 PREV-2 打印十字图

    历届试题 打印十字图   时间限制:1.0s   内存限制:256.0MB 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示: 对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并 ...

  7. hihoCoder#1079(线段树+坐标离散化)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学 ...

  8. Codeforce 101B. Buses(线段树or树状数组+离散化)

     Buses                                                                                               ...

  9. Redis 复制技术和高可用sentinel(哨兵模式)

    redis的复制技术和高可用(哨兵模式) 1 复制 为什么要复制 实现数据的多副本存储,从而可以实现服务的高可用 提供更好的读性能复制技术的关键点及难点 如何指定被复制对象 增量还是全量以及如何实现增 ...

  10. C++面试考点

    1.下面程序在x64下结果 struct st { int a; long long b; double c; }; int main() { st s; cout << &s.a ...