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

文章讲述了在Windows窗体程序开发中,如何处理在主线程初始化之前使用子线程访问控件的问题,推荐使用Control.Invoke或BeginInvoke方法,并介绍了使用Handle属性和IsHandleCreated属性进行线程同步的技巧。
摘要由CSDN通过智能技术生成

“在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));

有一个更巧妙的方法,只要在BenInvoke方法的调用语句前再加一句:

IntPtr i = this.Handle;

就OK了,这比死循环配合this.IsHandleCreated的判断方法更简洁,因为this.Handle这个属性本身就对应一个方法,取不到句柄,程序就不会向下进行。

PS:源码

        public DialogResult Show(string msg, string txt = "", MessageBoxButtons msgBtn = MessageBoxButtons.OKCancel)
        {
            IntPtr i = this.Handle;
            DialogResult dlgResult = DialogResult.None;
            if (this.IsHandleCreated)
            {
                this.Invoke(new EventHandler(delegate
                {
                     if (!string.IsNullOrEmpty(msg))
                     {
                         lblMsg.Text = msg;
                         if (!string.IsNullOrEmpty(txt))
                             this.TitleText = txt;
                         if (msgBtn == MessageBoxButtons.OK)
                         {
                             btnOK.Visible = false;
                             picQue.Visible = false;
                             picInfo.Visible = true;
                             btnCancel.Text = "确  定";
                         }
                         else
                         {
                             btnCancel.Text = "取  消";
                             btnOK.Visible = true;
                             picQue.Visible = true;
                             picInfo.Visible = false;
                         }
                         int line = lblMsg.Text.Length / 23;
                         lblMsg.Height = line > 0 ? 25 * line : 25;
                         this.Height = line > 0 ? 230 + line * 30 : 230;
                     }
                    dlgResult = FrmMsgBox.Instance.ShowDialog();
                }));
            }
            return dlgResult;
        }        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值