using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace treadTest { //定義委托 public delegate void ListBoxDelegate(); public partial class Form1 : Form { public Form1() { InitializeComponent(); } //委托處理方法(關(guān)聯(lián)與ListBoxDelegate) private void ListBox() { if (!listBox1.InvokeRequired)//如果在UI主線程操作ListBox, { listBox1.Items.Add(++CommonData.num);//則直接進行控件操作,“與UI主線程相關(guān)聯(lián)” listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; } else//如果是在另一線程操作ListBox,則啟用委托 listBox1.Invoke(new ListBoxDelegate(listShow)); } //定義對UI主線程控件的操作,“與AddAuto相關(guān)聯(lián)”。 private void listShow() { listBox1.Items.Add(CommonData.num); listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; } //定義線程函數(shù) private void AddAuto() { while (CommonData.Flag == 0) { CommonData.num++; Thread.Sleep(1000); ListBox();//不能直接控制UI上的控件,所以用該方法選擇使用委托 } } //在click事件中啟動多線程 private void btnStart_Click(object sender, EventArgs e) { //線程標志置0,表示開啟線程 CommonData.Flag = 0; //定義 ThreadStart的委托類型的參數(shù),并使該委托指向線程函數(shù) ListBoxDelegate mycn = new ListBoxDelegate(AddAuto); //實例化線程 Thread insertTxt = new Thread(new ThreadStart(mycn)); //啟動線程 insertTxt.Start(); } private void btnAbort_Click(object sender, EventArgs e) { CommonData.Flag = 1; } private void btnCtrlMain_Click(object sender, EventArgs e) { ListBox(); } private void btnReset_Click(object sender, EventArgs e) { CommonData.num = 0; } private void btnClear_Click(object sender, EventArgs e) { listBox1.Items.Clear(); } private void btnQuit_Click(object sender, EventArgs e) { Application.Exit(); } } //全局變量解決方案 public class CommonData { private static int _Flag = 0; private static int _num = 0; public static int Flag { get { return _Flag; } set { _Flag = value; } } public static int num { get { return _num; } set { _num = value; } } } } 總結(jié): 要使用多線程控制UI控件,必須用委托實現(xiàn)。調(diào)用控件的Invoke方法(Invoke方法的參數(shù)是一個委托類型的參數(shù))。 實現(xiàn)步驟: 1.聲明委托。 2.聲明委托處理函數(shù)(判斷是主線程控制UI控件,還是Invoke(多線程)控制UI控件)。 3.聲明一個線程實例,將線程函數(shù)的委托傳入ThreadStart()。 4.開啟該線程。 5.定義該線程函數(shù),欲控制UI控件,則調(diào)用第2步的委托處理函數(shù),他將自己判斷選擇用Invoke。 6.定義Invoke需要調(diào)用的函數(shù)(如本例的listShow函數(shù)) |
|