C# 執行序(Thread) 畫面更新
C# 執行序(Thread) 畫面更新
資料來源: https://home.gamer.com.tw/creationDetail.php?sn=4164649
https://home.gamer.com.tw/creationDetail.php?sn=3451015
第一種是設定元件屬性
Form.CheckForIllegalCrossThreadCalls = False;
這樣就不會跳出上述問題,只是非常不建議使用此方式 [我的最愛]
第二種為正規的方式,使用委派來跨執行緒存取UI
實際的做法如下,隨意舉個簡單的例子
片段程式範例:
private delegate void UpdateUI( String str, Control ctl); //宣告委派 private void updateText( String str, Control ctl) { if( this.InvokeReruired) { UpdateUI uu = new UpdateUI( updateText); this.Invoke( uu, str, ctl); } else { ctl.text = str; } }
完整程式範例:
using System; usingSystem.Collections.Generic; usingSystem.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; usingSystem.Windows.Forms; usingSystem.Threading; namespacethread_test2 { public partial class Form1 : Form { Thread _th; //宣告執行緒 public Form1() { InitializeComponent(); } //委派 UpdateUICallBack 來更新UI private delegate voidUpdateUICallBack_Text(int value, Control ctl); private delegate void UpdateUICallBack_Label(stringvalue, Control ctl); private voidbutton1_Click(object sender, EventArgs e) { Update_Label("start",label1); //更新Label _th = newThread(ExecuteInForeground); //宣告新執行緒做指定動作 _th.Start(); //開啟執行緒 //Thread.Sleep(1000); } private void ExecuteInForeground() { int i=0; while (true) { i++; Update_Text(i,textBox1); //更新textBox } } private void Update_Text(intvalue, Control ctl) { try{ //判斷這個TextBox的物件是否在同一個執行緒上 //當InvokeRequired為true時,表示在不同的執行緒上,所以進 //行委派 if (this.InvokeRequired) { UpdateUICallBack_Textuu = new UpdateUICallBack_Text(Update_Text); this.Invoke(uu,value, ctl); } Else //表示在同一個執行緒上了,所以可以正常的呼叫到這個TextBox物件 { ctl.Text =value.ToString(); } } catch { MessageBox.Show("執行緒被關閉"); } } private void Update_Label(stringvalue, Control ctl) { if (this.InvokeRequired) { UpdateUICallBack_Labeluu = new UpdateUICallBack_Label(Update_Label); this.Invoke(uu,value, ctl); } else { ctl.Text =value.ToString(); } } private voidbutton2_Click(object sender, EventArgs e) { Update_Label("stop",label1); _th.Abort(); //停止執行緒 } } }