在非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,如下:

01public Form1()
02{
03    InitializeComponent();
04    Control.CheckForIllegalCrossThreadCalls = false;
05}
06  
07private 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方法。

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

01private delegate void ParameterizedControlUpdate(params object[] args);
02  
03private delegate void ControlUpdateDelegate(Component c,
04    ParameterizedControlUpdate callback,
05    params object[] args);
06  
07private 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}

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

01private 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}

 

转载于:https://www.cnblogs.com/antony1029/archive/2010/10/10/1847176.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值