美文网首页
C#不能在控件上调用 Invoke 或 BeginInvoke

C#不能在控件上调用 Invoke 或 BeginInvoke

作者: 大龙10 | 来源:发表于2022-07-02 10:57 被阅读0次
参考资料: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);

相关文章

网友评论

      本文标题:C#不能在控件上调用 Invoke 或 BeginInvoke

      本文链接:https://www.haomeiwen.com/subject/xdzhbrtx.html