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. 阿里巴巴图标库iconfont上传svg后,显示不了图片

    AI里面选中图形,点对象-路径-轮廓化描边

  2. golang slice分割和append copy还是引用

    转载自:http://studygolang.com/articles/724 1. slice1:= slice[0:2] 引用,非复制,所以任何对slice1或slice的修改都会影响对方 dat ...

  3. Python mac安装mysqlclient的一个bug

    这是一个来自mysql官方的bug,反正我是看不懂. shuais-MBP:wxapp dandyzhang$ pipenv install mysqlclient Installing mysqlc ...

  4. Rich feature hierarchies for accurate object detection and semantic segmentation(理解)

    0 - 背景 该论文是2014年CVPR的经典论文,其提出的模型称为R-CNN(Regions with Convolutional Neural Network Features),曾经是物体检测领 ...

  5. LeakCanary监测内存泄漏的原理

    监测机制利用了Java的WeakReference和ReferenceQueue,通过将Activity包装到WeakReference中,被WeakReference包装过的Activity对象如果 ...

  6. java读写分离的实现

    1.  背景 我们一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案, 其中一个是主库,负责写入数据,我们称之为:写库: 其它都是从库,负责 ...

  7. Linker errors in Android NDK (undefined reference to `__cxa_end_cleanup')

    在 Android 中移植一个库(该库 使用了 libstlport )时 产生如下错误: ./obj/local/armeabi/objs/jniWrapper/native.o: In funct ...

  8. Python开发【第十篇】:模块

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  9. 《剑指offer》最小的k个数

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  10. 详解 CAP 定理 Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)

    CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三者不可得兼. 分布式 ...