antony--异域空间
性格左右命运,气度影响格局!

转自: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 }

 

posted on 2010-10-10 14:23  antony.net  阅读(410)  评论(0编辑  收藏  举报