WinForm中新开一个线程操作窗体上的控件(跨线程操作控件)GOOD

http://www.cnblogs.com/joey0210/p/3450379.html

最近在做一个winform的小软件(抢票的...)。登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是创建控件“lbl_loading_msg”的线程访问它。"百度一下,原来从.net framework 2.0开始,为了安全,不允许跨线程操作控件。解决办法如下:
1、先声明一个拥有委托类型的方法,作为代理 操作控件的代码:

复制代码
        /// <summary>
        /// 在线程中操作窗体的控件
        /// </summary>
        /// <param name="action"></param>
        private void OpeMainFormControl(Action action)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(action); //返回主线程(创建控件的线程)
            }
            else
            {
                action();
            }
        }
复制代码

2、然后在线程中,只要是对控件的操作都委托给上面的方法执行,不管是读取还是赋值:

复制代码
            Thread t = new Thread(new ThreadStart(delegate()
            {
                //执行一段费时的代码
                //......
                //线程中操作 控件,委托给invoker
                OpeMainFormControl(delegate()
                {
                    this.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示
                    this.toolStripStatusLabel1.Text = ""; //清空状态栏
                    this.btnlogin.Enabled = true;    //启用登录按钮
                });
            }));
            t.Start(); //启动线程
复制代码

上面代码需要注意的是:仅对控件操作的代码委托给this.invoke。上面委托操作的方法中的this是窗体对象,也就是创建控件的线程,this.invoker(action)就是将代码交给它来执行。这样就操作控件的代码就交给了创建控件的线程来执行了。我们不要将费时操作的代码也交给this.invoker来执行,不然就失去了线程的意义了(相当于没有开线程)。this.invoke又回到了主线程,会产生阻塞!下面代码会阻塞:

复制代码
                //将费时的代码也委托给 主线程(创建控件的线程)来执行,会阻塞窗体
                OpeMainFormControl(delegate()
                {
                //执行一段费时的代码
                //......
                //线程中操作 控件,委托给invoker
                
                    this.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示
                    this.toolStripStatusLabel1.Text = ""; //清空状态栏
                    this.btnlogin.Enabled = true;    //启用登录按钮
                });
复制代码

还有一点:如果对控件的操作代码没有委托给创建它的线程来执行(比如实例化另外一个窗口,show出来),它的一些设置会不起作用,比如:窗体初始显示位置等...

作者: 邹毅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值