Halcon视觉之家 - 51Halcon专注于机器视觉技术

 找回密码
 会员注册

QQ登录

只需一步,快速开始

扫一扫,微信登录

查看: 7546|回复: 15

[资料] C# 跨线程调用控件

[复制链接]
  • TA的每日心情
    开心
    昨天 10:57
  • 签到天数: 1292 天

    连续签到: 9 天

    [LV.10]以坛为家III

    420

    主题

    1739

    帖子

    6416

    积分

    Rank: 9

    积分
    6416

    突出贡献优秀版主荣誉管理论坛元老切换助手验证会员最佳新人

    发表于 2016-8-26 23:37:24 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    在C# 的应用程序开发中, 我们经常要把UI线程和工作线程分开,防止界面停止响应。  同时我们又需要在工作线程中更新UI界面上的控件,
    下面介绍几种常用的方法
    线程间操作无效
    界面上有一个button和一个label,  点击button会启动一个线程来更新Label的值
    1. private void button1_Click(object sender, EventArgs e)
    2.         {
    3.             Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel));
    4.             thread1.Start("更新Label");
    5.         }

    6.         private void UpdateLabel(object str)
    7.         {
    8.             this.label1.Text = str.ToString();
    9.         }
    复制代码
    运行后, 程序会报错 "跨线程操作无效,从不是创建"label1"的线程访问它"
    21140714-32f6d5deb3a545b2b40168f0cd28a2cf.png
    这是因为.NET禁止了跨线程调用控件, 否则谁都可以操作控件,最后可能造成错误。   

    下面介绍几种跨线程调用控件的方法

    第一种办法:禁止编译器对跨线程访问做检查这是最简单的办法, 相当于不检查线程之间的冲突,允许各个线程随便乱搞,最后Lable1控件的值是什么就难以预料了 (不推荐使用这种方法)
    1. public Form1()
    2.         {
    3.             InitializeComponent();
    4.             // 加入这行
    5.             Control.CheckForIllegalCrossThreadCalls = false;
    6.         }
    复制代码

    第二种办法: 使用delegate和invoke来从其他线程中调用控件调用控件的invoke方法,就可以控制控件了,例如
    1. private void button2_Click(object sender, EventArgs e)
    2.         {
    3.             Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel2));
    4.             thread1.Start("更新Label");
    5.         }

    6.         private void UpdateLabel2(object str)
    7.         {
    8.             if (label2.InvokeRequired)
    9.             {
    10.                 // 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
    11.                 Action<string> actionDelegate = (x) => { this.label2.Text = x.ToString(); };
    12.                 // 或者
    13.                 // Action<string> actionDelegate = delegate(string txt) { this.label2.Text = txt; };
    14.                 this.label2.Invoke(actionDelegate, str);
    15.             }
    16.             else
    17.             {
    18.                 this.label2.Text = str.ToString();
    19.             }
    20.         }
    复制代码

    第三种办法: 使用delegate和BeginInvoke来从其他线程中控制控件只要把上面的 this.label2.Invoke(actionDelegate, str); 中的 Invoke 改为BeginInvoke方法就可以了
    Invoke方法和BeginInvoke方法的区别是
    Invoke方法是同步的, 它会等待工作线程完成,
    BeginInvoke方法是异步的, 它会另起一个线程去完成工作线程

    第四种办法: 使用BackgroundWorker组件(推荐使用这个方法)BackgroundWorker是.NET里面用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。耗时的操作(如下载和数据库事务)。用法简单

    1. private void button4_Click(object sender, EventArgs e)
    2.         {
    3.             using (BackgroundWorker bw = new BackgroundWorker())
    4.             {
    5.                 bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    6.                 bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    7.                 bw.RunWorkerAsync("Tank");
    8.             }         
    9.         }

    10.         void bw_DoWork(object sender, DoWorkEventArgs e)
    11.         {      
    12.             // 这里是后台线程, 是在另一个线程上完成的
    13.             // 这里是真正做事的工作线程
    14.             // 可以在这里做一些费时的,复杂的操作
    15.             Thread.Sleep(5000);
    16.             e.Result = e.Argument + "工作线程完成";
    17.         }

    18.         void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    19.         {
    20.             //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了
    21.             this.label4.Text = e.Result.ToString();
    22.         }
    复制代码
    转摘自http://www.cnblogs.com/TankXiao/p/3348292.html

    无效附件更新 权限提升操作 删帖申请 举报以及其他需要帮助请加入QQ群:214663141 广告位招商 有意者联系

    该用户从未签到

    0

    主题

    4

    帖子

    434

    积分

    Rank: 2Rank: 2

    积分
    434
    发表于 2016-9-22 13:23:10 | 显示全部楼层
    谢谢分享啊,新人学习了
  • TA的每日心情

    2017-12-12 14:17
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    0

    主题

    17

    帖子

    40

    积分

    Rank: 1

    积分
    40
    发表于 2018-1-6 16:11:46 | 显示全部楼层
    谢谢分享啊,新人学习了
  • TA的每日心情
    无聊
    5 天前
  • 签到天数: 765 天

    连续签到: 1 天

    [LV.10]以坛为家III

    33

    主题

    226

    帖子

    1579

    积分

    Rank: 7Rank: 7Rank: 7

    积分
    1579

    活跃会员优秀版主切换助手验证会员

    发表于 2018-2-1 16:55:05 | 显示全部楼层
    谢谢分享啊,新人学习了
  • TA的每日心情

    2018-7-19 18:49
  • 签到天数: 57 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    18

    帖子

    92

    积分

    Rank: 5Rank: 5Rank: 5

    积分
    92

    切换助手验证会员

    发表于 2018-4-1 09:01:18 | 显示全部楼层

    谢谢分享啊,新人学习了
  • TA的每日心情

    2018-8-24 20:12
  • 签到天数: 44 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    58

    帖子

    137

    积分

    Rank: 1

    积分
    137
    发表于 2018-4-2 09:05:01 | 显示全部楼层
    谢谢分享,新人学习
    您需要登录后才可以回帖 登录 | 会员注册

    本版积分规则

    视觉培训招生
    大恒图像X

    建议您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流浏览器浏览本网站

    51Halcon会员技术交流会员技术交流 | 51Halcon官方客服咨询官方客服咨询 | Halcon切换助手使用反馈切换助手使用

    算子查询| 申请友链| 小黑屋| 手机版| Archiver|

    © 2015-2021 51Halcon机器视觉  X3.4  粤ICP备15095995号 粤公网安备44030602000670号

    快速回复 返回顶部 返回列表