在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke


在Window窗体程序开发的时候,如果使用多线程编程,在子线程中访问主线程窗体内的控件,就需要使用控件的Control.Invoke方法或者BeginInvoke方法。但是有时候因为Window执行速度太快,尤其是你写代码的时候在InitializeComponent();完成之前起了一个线程去执行某些操作,涉及到窗体控件的,当你在调用Control.Invoke的时候,就可能出现 “在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”错误。

解决的办法就是让线程等待,直到窗口句柄创建完毕:
 //防止在窗口句柄初始化之前就走到下面的代码
while (!this.IsHandleCreated)
 {
    ;
 }
this.BeginInvoke(new ProListIndexChangedDelegate(GetProLyric));

//根据不同情况也可以:
 if (this.IsHandleCreated)
BeginInvoke(new ProListIndexChangedDelegate(GetProLyric));

 

我的广播播出系统有多个线程(实际上是计时器)在监视并改变播放器媒体及播出窗口UI,同时有个歌词同步显示窗口(与播放器媒体同步)。歌词显示窗口我是设置窗口隐藏与可视,并没有关闭释放资源特别是移除播放器媒体变化事件,导致窗口句柄创建之前就执行窗口的BeginInvoke,碰到该异常,经过多次测试才知道是歌词同步显示造成的。
难道与Form的 Hide(); Show();也有关?(窗口设置ShowInTaskbar = false;)
Hide()后this.IsHandleCreated始终为 false?

posted on 2009-07-17 11:17  jdmei520  阅读(2374)  评论(0编辑  收藏  举报

导航