CSharp學習筆記之九 多線程編程

今天就來學習一下C#中的線程和進程的問題吧
在C#中要操作線程就要藉助Thread這個類來進行的一些操作的,首先要事例化一個thread的類,再在這個類的基礎上進行操,在實例化Thread的實例,需要提供一個委託,在實例化這個委託時所用到的參數是線程將來啓動時要運行的方法。在.net中提供了兩種啓動線程的方式,一種是不帶參數的啓動方式,另一種是帶參數的啓動的方式。

下面給出一個多線程的操作問題的例子:
public class Test
{
    static public void ShowInfo()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("1線程輸出的信息");
            Thread.Sleep(100);
        }
    }
    public static void Main(string[] argvs)
    {

        Thread myThread = new Thread(new ThreadStart(Test.ShowInfo));
        myThread.Start();
        for (int i = 0; i < 10; i++ )
        {
            Console.WriteLine("主線程執行完畢!");
            Thread.Sleep(100);
        }
        Console.ReadKey();
    }
}

這個例子中是將主函數作爲一個主線程,定義一個新的線程myThread 的線程,然後通過Start方法來開始該線程的。當然在實例化這個線程的時候我們要傳入一個委託Test.ShowInfo作爲參數。通過這個委託來將具體的方法給實現的。
執行結果如下圖所示:

 
當然,每次的執行的結果是不一樣的,這個是和電腦的CPU的線程調度有關係的。
對於多線程,很多的時候是有數據的交換的,比如說數據的傳入和數據的傳出,但是在都線程中是怎麼傳入參數的呢,當然如果要在實例化線程時要帶一些參數,就不能用ThreadStart委託作爲構造函數的參數來實例化Thread了,而要ParameterizedThreadStart委託,和ThreadStart一樣的是它也是線程啓動時要執行的方法,和ThreadStart不同的是,它在實例化時可以用一個帶有一個Object參數的方法作爲構造函數的參數,而實例化ThreadStart時所用到的方法是沒有參數的。
 爲什麼是Object這樣的參數呢?很簡單,因爲在.net中Object是所有類型的基類,用它可以表示Array(數組)、Interface(接口)、ValueType(值類型,如bool,byte,char,short,int,float,long,double等)、class(類)等.net中的類型。當然,這也意味着如果你要啓動一個線程,給它傳遞一個int類型參數時,必須在啓動方法中進行相應的類型轉換。
 下面就是一個例子,在啓動線程時指定了線程的名字,代碼如下
static public void ShowInfo(object threadName)
    {
        string name = threadName as string;
        for (int i = 0; i < 5; i++ )
        {
            Console.WriteLine("{0}在執行!\n", threadName);
            Thread.Sleep(100);
        }
    }
    public static void Main(string[] argvs)
    {
        Thread myThread = new Thread(new ParameterizedThreadStart(Test.ShowInfo));
        myThread.Name = "子線程";
        myThread.Start(myThread.Name);

        ShowInfo("主線程");

        Console.ReadKey();
    }

運行結果如下圖所示
 
 


當然這個例子只是實現了傳入一個參數的例子,但是,很多的時候,我們會要傳入很多個參數的,但是這個時候我們要怎麼做額。前面已經介紹了,在用ParameterizedThreadStart它來進行初始化一個線程的時候,可以傳入一個object的類型,我們都知道,object幾乎是可以和任何的類型進行轉化的,這個時候我們就會想到要引入一個外部類來實現傳入多個參數的問題。
下面通過一個例子來演示通過引入外部類的方法來傳入多個參數的具體實現:

namespace StartThread
{
    class MyThreadParameter
    {
        private int interval;
        private int loopCount;
        /// <summary>
        /// 循環次數
        /// </summary>
        public int LoopCount
        {
            get { return loopCount; }
        }

        /// <summary>
        /// 線程的暫停間隔
        /// </summary>
        public int Interval
        {
            get { return interval; }
        }
        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="interval">線程的暫停間隔</param>
        /// <param name="loopCount">循環次數</param>
        public MyThreadParameter(int interval, int loopCount)
        {
            this.interval = interval;
            this.loopCount = loopCount;
        }
    }
    class Program
    {
        int interval = 200;
        static void Main(string[] args)
        {
            Program p = new Program();

            Thread parameterThread = new Thread(new ParameterizedThreadStart(p.MyParameterRun));
            parameterThread.Name = "Thread A:";
            MyThreadParameter paramter = new MyThreadParameter(50, 20);
            parameterThread.Start(paramter);

            Console.ReadKey();
        }


        /// <summary>
        /// 帶多個參數的啓動方法
        /// </summary>
        /// <param name="ms">方法參數</param>
        public void MyParameterRun(object ms)
        {
            MyThreadParameter parameter = ms as MyThreadParameter;//類型轉換
            if (parameter != null)
            {
                for (int i = 0; i < parameter.LoopCount; i++)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + "系統當前時間毫秒值:" + DateTime.Now.Millisecond.ToString());
                    Thread.Sleep(parameter.Interval);//讓線程暫停
                }
            }
        }
    }
}


運行結果如下圖所示


當然還有另外的一種方法,那個方法也是要引入外部類的東西的,但是具體的線程的創建和線程的執行都是在這個類中進行的操作的,具體的實現這裏就不上例子了,大家可以思考一下。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章