在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
2016-07-21 19:29
351 查看
今天关闭一个窗体,报出这样的一个错误"在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke。",这个不用多想,肯定是那个地方没有释放掉。
既然碰到这个问题,先不说问题本身,来说说其他的一些事情。
winform最常见的是datagridview这个控件,不管重写还是怎么,很多数据的操作都是用datagridview来展示的,因此,它的异步调用也算是比较多的一类了。
比如:
1从数据库中读取大量数据(所谓的分页读取不在这个范畴)
2操作datagridview,然后一段时间后改变或者填充dtagridview
3datagridview本身的一些效果,比如旋转的延时等待,或者其他
不用异步肯定会出现死机的情况,用了异步可能也要注意一些情况
一个简单的例子:
一个showdialog窗体里有个一个datagridview,我用异步读取数据,但是没读完,我关了窗体,这时候,数据读完了,要执行
datagridview.source=??
这个时候,会出错,可能不是"在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke。"这个错误,而是"资源已经释放之类的",那咱们看看下面的几个方法。
1this.components这个属性
既然碰到这个问题,先不说问题本身,来说说其他的一些事情。
winform最常见的是datagridview这个控件,不管重写还是怎么,很多数据的操作都是用datagridview来展示的,因此,它的异步调用也算是比较多的一类了。
比如:
1从数据库中读取大量数据(所谓的分页读取不在这个范畴)
2操作datagridview,然后一段时间后改变或者填充dtagridview
3datagridview本身的一些效果,比如旋转的延时等待,或者其他
不用异步肯定会出现死机的情况,用了异步可能也要注意一些情况
一个简单的例子:
一个showdialog窗体里有个一个datagridview,我用异步读取数据,但是没读完,我关了窗体,这时候,数据读完了,要执行
datagridview.source=??
这个时候,会出错,可能不是"在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke。"这个错误,而是"资源已经释放之类的",那咱们看看下面的几个方法。
1this.components这个属性
///<summary> ///Requireddesignervariable. ///</summary> privateSystem.ComponentModel.IContainercomponents=null; 每一个Designer.cs里都有一个这个东西,IContainer接口相当于是一个容器,一个页面全部的东西都会放在里面,你拖一个button或者label都会放在里面,笔者觉得,这个其实就是wpf的一个容器的概念,你可以从root寻找到每一个控件,而IContainer也可以找到你想要的控件,Active激活或者不激活会用到这个。 窗体释放,components也会释放
///<summary> ///Cleanupanyresourcesbeingused. ///</summary> ///<paramname="disposing">trueifmanagedresourcesshouldbedisposed;otherwise,false.</param> protectedoverridevoidDispose(booldisposing) { if(disposing&&(components!=null)) { components.Dispose(); } base.Dispose(disposing); } 这个方法会释放,所以可以当做判断窗体是否释放的一个依据,但是笔者不推举 2this.IsDisposed 这个是判断是否已经释放了,用这个判断比components要好一些,具体的原因是components在窗体关闭后可能没有释放,而this.IsDisposed窗体必然已经释放了,当窗体是MID模式的时候,由于线程或其他原因,窗体的关闭可能不会释放 3IsHandleCreated 句柄是否创建 当子空间句柄创建了,而它的parent的句柄由于其他原因没有创建或者已经释放了,则也会出现其他问题,所以这个可以通过Parent.IsHandleCereated来盘点父句柄是否存在或者已经创建 上面几个方法可以组合用,笔者判断的时候差不多用后两个 现在说说这两个Invoke和BeginInvoke Control.Invoke:在拥有此控件的线程上先进先出顺序执行委托 Control.BeginInvoke:在拥有此控件线程上异步执行委托,也就是可能并非顺序执行,这个有点熟悉,貌似说过了 最后说说解决方法: 在 Invoke(....)之前加上1this.components==null2this.IsDisposed3 IsHandleCreated来return不执行invoke就可以,当然只是我针对自己遇到的解决的,可能并不适合其他的,但是总不会脱离其中
set { if(IsDisposed||!this.Parent.IsHandleCreated)return; this.Invoke((System.Action)delegate() { }); }
相关文章推荐
- Python学习-反射相关函数
- 设计模式-1、简单工厂模式
- 【机器学习入门】线性回归的概率解释
- 构造方法的重载
- 【软件工程】滨江学院 李振宏 软件工程 考点整理
- hdu 2647(拓扑排序)
- java基础Day02
- 引导页-通过简单的方法给app加入简单的引导页面
- LeetCode 371. Sum of Two Integers
- javascript event(事件对象)详解
- 2016 Multi-University Training Contest 2
- 如何实现 Android 应用的持续部署?
- Find MaxXorSum 经典字典树求异或最大值
- 安卓刮刮乐效果demo
- Word Search
- Codeforces 77A Heroes
- Linux Firewall ---iptables
- 1005. Spell It Right (20)-PAT甲级真题
- Html5的Web存储和WebSql
- hdu-5742 It's All In The Mind(数学)