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; }