参考资料:https://www.cnblogs.com/idea555/articles/14808605.html
https://blog.csdn.net/baidu_38995168/article/details/115478182
1、现象:
今天关闭一个窗体,报出这样的一个错误:
"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。"。
这个不用多想,肯定是那个地方没有释放掉。
2、原因
winform最常见的是datagridview这个控件,不管重写还是怎么,很多数据的操作都是用datagridview来展示的,因此,它的异步调用也算是比较多的一类了。
比如:
- 1 从数据库中读取大量数据(所谓的分页读取不在这个范畴)
- 2 操作datagridview,然后一段时间后改变或者填充dtagridview
- 3 datagridview本身的一些效果,比如旋转的延时等待,或者其他
不用异步肯定会出现死机的情况,用了异步可能也要注意一些情况:
- 一个showdialog窗体里有个一个datagridview,用异步读取数据,但是没读完,关了窗体,这时候,数据读完了,要执行datagridview.source = ??这个时候,就会出错。
3、有关方法
- this.components 这个属性
每一个Designer.cs里都有一个这个东西,IContainer接口相当于是一个容器,一个页面全部的东西都会放在里面,你拖一个button或者label都会放在里面,笔者觉得,这个其实就是wpf的一个容器的概念,你可以从root寻找到每一个控件,而IContainer也可以找到你想要的控件,Active激活或者不激活会用到这个。
窗体释放,components 也会释放。这个方法会释放,所以可以当做判断窗体是否释放的一个依据 - this.IsDisposed
这个是判断是否已经释放了,用这个判断比 components 要好一些,具体的原因是components在窗体关闭后可能没有释放,而this.IsDisposed窗体必然已经释放了,当窗体是MID模式的时候,由于线程或其他原因,窗体的关闭可能不会释放 - IsHandleCreated
句柄是否创建
当子空间句柄创建了,而它的parent的句柄由于其他原因没有创建或者已经释放了,则也会出现其他问题,所以这个可以通过Parent.IsHandleCereated来盘点父句柄是否存在或者已经创建
4、解决办法
增加了一条判断语句,解决问题
if (IsDisposed || !this.IsHandleCreated) return;
部分程序
Bitmap bitmap = new Bitmap((int)ImageInfo.iWidth, (int)ImageInfo.iHeight, (int)ImageInfo.iWidth * 3, PixelFormat.Format24bppRgb, pRGBFrame);
if (m_isNeedSave)
{
bitmap.Save("d:\\camera_test1.bmp");
m_isNeedSave = false;
}
//////////////////////////////////显示
if (IsDisposed || !this.IsHandleCreated) return;
///////
this.BeginInvoke(new Action(() =>
{
this.pictureBox.Image = bitmap;
}));
//释放由 CameraGetRawImageBuffer 获得的缓冲区
CKAPI.CameraReleaseFrameHandle(m_hCamera, hBuf);
}
CKAPI.CameraPause(m_hCamera);
网友评论