Invoke()的作用是:在应用程序的主线程上执行指定的委托。一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();
1 //测试的窗体 2 public class TestForm : Form 3 { 4 //创建一个Button对象 5 private Button button = new Button(); 6 //构造函数 7 public TestForm() 8 { 9 //设置按钮的属性 10 button.Size = new Size(150, 100); //大小 11 button.Click += Button1_Clicked; //注册事件 12 button.Text = "点击开始测试"; //设置显示文本 13 this.Controls.Add(button); //添加到窗体上 14 this.Text = "多线程范例"; //设置窗体的标题栏文本 15 } 16 //按钮的Click事件响应方法 17 public void Button1_Clicked(object sender, EventArgs e) 18 { 19 //启动一个线程 20 new Thread(ThreadProc).Start(); 21 } 22 //线程函数 23 public void ThreadProc() 24 { 25 //this.Invoke就是跨线程访问ui的方法,也是本文的范例 26 //首先invoke一个匿名委托,将button对象禁用 27 this.Invoke((EventHandler)delegate 28 { 29 button.Enabled = false; 30 }); 31 32 //记录一个时间戳,以演示倒计时效果 33 int tick = Environment.TickCount; 34 while (Environment.TickCount - tick < 1000) 35 { 36 //跨线程调用更新窗体上控件的属性,这里是更新这个按钮对象的Text属性 37 this.Invoke((EventHandler)delegate 38 { 39 button.Text = (1000 - Environment.TickCount + tick).ToString() + "微秒后开始更新"; 40 }); 41 //做一个延迟,避免太快了,视觉效果不好。 42 Thread.Sleep(100); 43 } 44 //演示,10次数字递增显示 45 for (int i = 0; i < 10; i++) 46 { 47 this.Invoke((EventHandler)delegate 48 { 49 button.Text = i.ToString(); 50 }); 51 Thread.Sleep(200); 52 } 53 //虽然不是循环内,请不要忘记,你的调用依然在辅助线程中,所以,还是需要invoke的。 54 //还原状态,设置按钮的文本为初始状态,设置按钮可用。 55 this.Invoke((EventHandler)delegate 56 { 57 button.Text = "点击开始测试"; 58 button.Enabled = true; 59 }); 60 } 61 }