天天看點

C# 多線程控制控件執行個體

該執行個體功能為“多線程控制UI控件”,線程函數實作自動加1。界面如下:

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();

        }

        //委托處理方法(關聯與ListBoxDelegate)

        private void ListBox()

            if (!listBox1.InvokeRequired)//如果在UI主線程操作ListBox,

            {

                listBox1.Items.Add(++CommonData.num);//則直接進行控件操作,“與UI主線程相關聯”

                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];

            }

            else//如果是在另一線程操作ListBox,則啟用委托

                listBox1.Invoke(new ListBoxDelegate(listShow));

        //定義對UI主線程控件的操作,“與AddAuto相關聯”。

        private void listShow()

            listBox1.Items.Add(CommonData.num);

            listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];

        //定義線程函數

        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的委托類型的參數,并使該委托指向線程函數

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

}

總結:

        要使用多線程控制UI控件,必須用委托實作。調用控件的Invoke方法(Invoke方法的參數是一個委托類型的參數)。

實作步驟:

         1.聲明委托。

          2.聲明委托處理函數(判斷是主線程控制UI控件,還是Invoke(多線程)控制UI控件)。

         3.聲明一個線程執行個體,将線程函數的委托傳入ThreadStart()。

         4.開啟該線程。

         5.定義該線程函數,欲控制UI控件,則調用第2步的委托處理函數,他将自己判斷選擇用Invoke。

         6.定義Invoke需要調用的函數(如本例的listShow函數)

//*********************************************************************************************************************************

      在上例中,隻是完成了多線程控制主線程控件的功能,如果能手動和自動同時通路全局變量時,就有可能出現線程不同步的問題。以下主要利用lock線程鎖來修改解決方案,使線程同步,注意代碼帶動的地方。

                listBox1.Items.Add(CommonData.plus());//則直接進行控件操作,“與UI主線程相關聯”

            listBox1.Items.Add(CommonData.plus());

        public static int plus()

            lock (new object())

                return _num++;

本文轉自黃聰部落格園部落格,原文連結:http://www.cnblogs.com/huangcong/archive/2010/03/26/1697090.html,如需轉載請自行聯系原作者