Cannot access a disposed object

 

带有UIC#程序在初始化界面或者由用户触发某一UI更新的时候常常会遇到这样的JIT异常:

System.ObjectDisposedException: Cannot access a disposed object.

Object name: 'XXXX'.

从字面上理解,就是无法得到一个已经被终止的对象。那么在什么情况下这样的事情会发生呢?

看一段代码就能够理解了。

ContractedBlock.gif ExpandedBlockStart.gif Code
           public AuthenticationForm()
            {
                
// Required for Windows Form Designer support

                InitializeComponent();

                
// TODO: Add any constructor code after InitializeComponent call

                
this.action = FormAction.View;

                AppButtons.AppParent 
= this;

                
this.EDITCTLS = new Control[] {RoleDGrid, RegionDGrid, UserNameTBox, CheckAllButton, ClearAllButton, ActiveCkBox, RoleCheckAllButton, RoleClearAllButton};

                
this.Initialization();
                BeginAuth(
"GetUser"new object[]{AddUserButton});

            }

Main方法执行了MainForm的初始化,完成必要组件实例化和数据导入,开始等待用户输入。

Ok,用户这时候点击了一个登录菜单,以上form constructor代码经事件触发,开始执行,啪啪啪完成新form的初始化,最后一步看到BeginAuth方法,它要完成对用户的验证,如果验证通过,登录Form要显示,如果验证失败,主进程要返回错误信息,终止此form的所有资源。

但请注意,这个BeginAuth可不能随便写写。看看这段BeginAuth的实现吧:

      

 

 DataManager.SendAsyncWSRequest( this this .displayDelegate, spName, DataManager.XMLDOC.InnerXml, hash);

DataManager是数据底层传输处理的接口,它是通用的。DataManager要发出WebService的数据请求,然后获得回答(response),再通过this传入的CallingForm实例调用Form的另一个方法EndAuth

callingForm.EndAuth(resultXML, spName, hash,  new  ResponseArgs( false , errorNode.InnerXml, AsyncFailType.WSCaught));

EndAuth要解析WebServiceresponse,判断是否验证通过,和相应Form的资源如何响应。以下是简单的EndAuth实现:

ContractedBlock.gif ExpandedBlockStart.gif Code
         if(resp.Success == false)
          {
                MessageBox.Show(re.Msg, spName 
+ ": WebService call fails");

                
base.EndAuth(re.Msg, spName, hash, re);

                
this.Close();

                
return;

           }

           
else

                UpdateDisplay();

Form在失败验证之后会被马上close掉,换句话说,this.Close()会终止form之前初始化的所有组件,GC不知不觉开始回收内存。。。。

本文的主题在这个return之后发生了。return一完成,它退到哪儿了?对,之前form constructorBeginAuth之后,也就是说,form还没有“出生”就已经被“堕”了。但被“堕”不等于什么也没有(null),毕竟“尸骨”犹在。MainForm在得知sub-form constructor返回以后就会执行类似显示form的方法Show()。要秀就要拿到form句柄,但老子(mainform)拿到的却是一个夭折的孩子。。。当然怎么show也于事无补了。悲惨的Cannot access a disposed object异常就这样发生了。由于是从Mainform触发,它会直接影响主进程,导致程序崩溃。

知道了来龙去脉,那么怎样避免呢?很简单,

  1. 1.      不要在constroctor 没有做完之前就任意终止资源(原则性)

        拿示例来说的话,就是不要将BeginAuth方法置于构造方法内,置于Form_load()方法中不失为一良策。

  1. 2.        在拿来show 之前要判断是否为空或已被终止(辅助性)

 

  if  (subForm !=   null   &&   ! subForm.IsDisposed)

    subForm.Show();

 

转载于:https://www.cnblogs.com/harryaya/archive/2007/11/26/972351.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值