C#对Windows 窗体控件进行线程安全调用

  Windows窗体上假设有一个TextBox控件,我们需要在另外的线程中改变它的Text值。

        错误的代码(非安全线程访问)如下:

         private Thread demoThread = null;
        //在按钮单击事件中新建线程
        private void button1_Click(object sender, EventArgs e)
        {
            this.demoThread =
                new Thread(new ThreadStart(this.ThreadProcUnsafe));
            this.demoThread.Start();
        }
        private void ThreadProcUnsafe()
        {
            //假设存在TextBox控件,名称为textBox1,对其Text属性赋值
            this.textBox1.Text = "This text was set unsafely.";
        }

        运行,点击“button1”,哦,有异常了:从不是创建控件textBox1(控件名称) 的线程访问它。初看这句话时我的感觉是这些字都认识,就是不明白说得什么(好多异常和说明都有这个特点)。细细琢磨后才反应过来,这句异常的意思是,创建textBox1的线程与访问textBox1的线程不是同一个线程。上例中创建textBox1的线程是在主窗体中,而修改它的值的操作却在另一个线程中,因而无法对textBox1进行访问。由此可得出一个结论:每个线程只能操作自己创建的控件,对于其他线程来说是封闭的,不可访问的。

        当然,这只是一般情况。要想从其他线程访问textBox1,需要使用委托和其他一些属性与方法。请看下面方法。

        正确的做法(线程安全访问):

        private Thread demoThread = null;
        //委托,实现线程访问控件
        delegate void SetTextCallback(string text);
        private void button1_Click(object sender, EventArgs e)
       {
            this.demoThread =new Thread(new ThreadStart(this.ThreadProcSafe));
            this.demoThread.Start();
       }
        //线程调用的方法
        private void ThreadProcSafe()
        {
            this.SetText("This text was set safely.");
        }
        private void SetText(string text)
        {
            //使用控件的InvokeRequired属性,该属性比较控件的调用线程与创建线程的ID,若不是同一个线程则执行委托;
           //若调用线程与创建线程是同一个线程,则直接访问控件,对其进行操作。
            if (this.textBox1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.textBox1.Text = text;
            }
        }

        对于第一种方式,可以在代码中加入这样一句:Control.CheckForIllegalCrossThreadCalls = false;表示不检查控件的非法跨线程调用。程序就可正确运行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值