zoukankan      html  css  js  c++  java
  • 在非UI线程中改变UI控件属性的通用方法

    转自:http://www.sunnychen.org/trackback.asp?tbID=124&action=addtb&tbKey=43c0d85c8d6d5dcc018d174276ac098da9245500

    在.NET中如需在非UI线程中改变UI控件属性时,CLR会抛出异常,提示无法在非UI线程中更新界面上的控件(Cross-thread operation not valid)。一般情况下有两种解决办法。第一种就是设置Control的静态属性CheckForIllegalCrossThreadCalls为False,如下:

    01 public Form1()
    02 {
    03     InitializeComponent();
    04     Control.CheckForIllegalCrossThreadCalls = false;
    05 }
    06   
    07 private void button1_Click(object sender, EventArgs e)
    08 {
    09     Thread thread = new Thread(() =>
    10     {
    11         for (int i = 0; i < 100000; i++)
    12         {
    13             label1.Text = i.ToString();
    14             label1.Refresh();
    15         }
    16     });
    17     thread.Start();
    18 }

    另一种办法,就是使用委托,根据控件的InvokeRequired属性判断当前控件的更新操作是否是在另一个线程中。如果是,则使用委托进行方法调用并更新控件。但是这种方法有个缺点,就是需要针对每个控件的属性设置方式创建一些单独的委托和方法,这些委托和方法仅仅是在解决跨线程操作的时候使用。比如,你在另一个线程中需要修改某个label的text时,你就需要创建一个SetLabelText方法,假设你还需要更新TextBox的text,那么你还需要另外创建一个SetTextBoxText方法。

    通过下面的委托和方法的定义,我们实现了“一次定义,多次使用”。请看:

    01 private delegate void ParameterizedControlUpdate(params object[] args);
    02   
    03 private delegate void ControlUpdateDelegate(Component c,
    04     ParameterizedControlUpdate callback,
    05     params object[] args);
    06   
    07 private void DelegatedControlUpdate(Component c,
    08     ParameterizedControlUpdate callback,
    09     params object[] args)
    10 {
    11     Control target = (c is Control) ? (c as Control) : this;
    12     if (target.InvokeRequired)
    13     {
    14         ControlUpdateDelegate d = DelegatedControlUpdate;
    15         target.Invoke(d, new object[] { c, callback, args });
    16     }
    17     else
    18     {
    19         callback(args);
    20     }
    21 }

    于是,上面的例子可以改为:

    01 private void button1_Click(object sender, EventArgs e)
    02 {
    03     Thread thread = new Thread(() =>
    04     {
    05         for (int i = 0; i < 100000; i++)
    06         {
    07             DelegatedControlUpdate(label1, args =>
    08                 {
    09                     label1.Text = (string)args[0];
    10                     label1.Refresh();
    11                 }, i.ToString());
    12         }
    13     });
    14     thread.Start();
    15 }
    antony
    :antony1029@163.com
    :http://antony1029.cnblogs.com
  • 相关阅读:
    基础很重要~~04.表表达式-上篇
    【T-SQL基础】03.子查询
    【T-SQL基础】02.联接查询
    【T-SQL基础】01.单表查询-几道sql查询题
    【.Net底层剖析】3.用IL来理解属性
    SQL-基础知识
    IL指令速查
    黑客成长之路-01.新手篇-设置路由器
    《拆掉思维里的墙》~~想跳槽的同学可以先看看这本书!
    【解决方案】安装vssdk_full.exe遇到的问题
  • 原文地址:https://www.cnblogs.com/antony1029/p/1847176.html
Copyright © 2011-2022 走看看