C#之Invoke与BeginInvoke即控件值实时更新

2 篇文章 1 订阅

在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误 的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。我们将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用。如果从线程外操作windows窗体控件,那么就需要使用Invoke或者BeginInvoke方法,通过一个委托把调用封送到控件所属的线程上执行。

实例:使用While读取PLC的值显示到面板中

1、第一种实时读取PLC的方法:

        private void button1_Click(object sender, EventArgs e)
        {
            thread = new Thread(new ThreadStart(ShowData));
            thread.Start();   //使用线程调用
        }

        //显示实时数据
        public void ShowData()
        {
            while (true)
            {
                this.Invoke((EventHandler)delegate
                {
                    label1.Text = siemensS7Net.ReadInt16(tb_ad_1).Content.ToString();
                    label2.Text = siemensS7Net.ReadInt16(tb_ad_2).Content.ToString();
                    label3.Text = siemensS7Net.ReadInt16(tb_ad_3).Content.ToString();
                });
                Thread.Sleep(1000);
            }
        }

2、第二种实时读取PLC的方法: 

 //声明委托对应的方法
        public void ShowData(string param1, string parm2)
        {
            this.label1.Text = param1;
            this.label2.Text = parm2;
        }

        //声明委托
        public delegate void UpdateForm_dl(string str1, string str2);
        
        //调用委托
        private void Calldelegate()
        {
            while (true)
            {
                Thread.Sleep(1000);
                string a = siemensS7Net.ReadInt16(tb_ad_1).Content.ToString();
                string b = siemensS7Net.ReadInt16(tb_ad_2).Content.ToString();
                this.BeginInvoke(new UpdateForm_dl(ShowData), new object[] { a, b });
            }
        }

        //新线程入口
        public void DoWork()
        {
            Calldelegate();
        }

调用

            Thread thread = new Thread(new ThreadStart(DoWork));
            thread.Start();   //使用线程调用

3、第三种实时读取PLC的方法:

两者的区别就是一个导致工作线程等待,而另外一个则不会。BeginInvoke立即插入主线程中执行,而Invoke 要等主线程结束才执行。即:

Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托。

Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上异步执行指定委托。

(一)、Control的Invoke和BeginInvoke
        我们要基于以下认识:
(1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。
(2)Control的Invoke和BeginInvoke的参数为delegate,委托的方法是在Control的线程上执行的,也就是我们平时所说的UI线程。

而所谓的“一面响应操作,一面添加节点”永远只能 是相对的,使 UI 线程的负担不至于太大而已,因为界面的 正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算, 而 将对纯粹的界 面更 新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。

1、Invoke的作用与用法

Invoke()的作用是:在应用程序的主线程上执行指定的委托。

一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();》》线程会在UI线程和辅助线程之间相互转换 

 

4、第四种实时读取PLC的方法:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值