System.Windows.Forms.Timer 的timer是在主线程上执行的,因此在timer的tick事件中操作界面上的控件不会发生线程的安全性检测。
Control的invoke和begininvoke方法的比较:
invoke方法:使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。
private delegate void InvokeDelegate(); private void InvokeMethod() { //C代码段 } private void butInvoke_Click(object sender, EventArgs e) { //A代码段....... this.Invoke(new InvokeDelegate(InvokeMethod)); //B代码段...... }
invoke执行的顺序是A->C->B
beginInvoke异步方法。
Control的BeginInvoke private delegate void BeginInvokeDelegate(); private void BeginInvokeMethod() { //C代码段 } private void butBeginInvoke_Click(object sender, EventArgs e) { //A代码段....... this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod)); //B代码段...... }
begininvoke执行的顺序是A->B->C
下面列出几种control的invoke方法使用:
1) Action的lambda方法的使用
Control.invoke(new Action(()=>{.....;}));
new Thread(() => { while (true) { label1.BeginInvoke(new MethodInvoker(() => { label1.Text = System.DateTime.Now.ToString(); })); Thread.Sleep(1000); } }) { IsBackground = true }.Start();
2)实例委托
private delegate void ChangeTxt(); void time_Elapsed(object sender,System.Timers.ElapsedEventArgs e) { ChangeTxt changetxtDelegate=new ChangeTxt(change); textBox1.Invoke(changetxtDelegate);
//或者直接textBox1.Invoke(new ChangeTxt(change));
}
private void change() { textBox1.Text = (a++).ToString(); }
3)传参数
private delegate void showtest(string text); private void run() { showtest st = new showtest(show); for (int i = 0; i < 100000; i++) { textBox1.Invoke(st, i.ToString()); } } void show(string test) { textBox1.Text = test; }