C# 執行序(Thread) 畫面更新

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(); //停止執行緒
                }
        }
}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *