首頁 > 軟體

C#中Thread(執行緒)和Task(任務)範例詳解

2022-03-19 13:03:21

執行緒

執行緒:對於所有需要等待的操作,例如移動檔案,資料庫和網路存取都需要一定的時間,此時就可以啟動一個新的執行緒,同時完成其他任務。一個程序的多個執行緒可以同時執行在不同的CPU上或多核CPU的不同核心上。

一個應用程式啟動時,會啟動一個程序(應用程式的載體),然後程序會啟動多個執行緒。

一,使用Thread類啟動執行緒和資料傳輸

使用Thread類可以建立和控制執行緒,Thread建構函式是一個無參無返回值的委託型別。

1️⃣對Thread傳入一個無參無返回型別的方法-ThreadStart。

    public delegate void ThreadStart();

範例:

        static  void test()
        {
            Console.WriteLine("test is start");
            Console.WriteLine("test is running");
            Thread.Sleep(3000);
            Console.WriteLine("test is completed");
        }

        static void Main(string[] args)
        {
            Thread th = new Thread(test);
            th.Start();
            Console.WriteLine("main is completed");
        }

2️⃣對Thread傳入一個匿名方法(或lambda表示式)。用於傳入的方法程式碼簡單的情況

        static void Main(string[] args)
        {
            //lambad表示式
            Thread th = new Thread(()=> {
                Console.WriteLine("子執行緒1-ID:" + Thread.CurrentThread.ManagedThreadId);
            });
            th.Start();
            //匿名方法
            Thread th2 = new Thread(delegate ()
            {
                Console.WriteLine("子執行緒2-ID:" + Thread.CurrentThread.ManagedThreadId);
            });
            th2.Start();
            Console.WriteLine("main is completed");
        }

3️⃣對Thread傳入一個無返回值有參方法-ParameterizedThreadStart,該引數只能是object型別且只能有一個引數。

    public delegate void ParameterizedThreadStart(object? obj);

範例:

        static void download(object o)
        {
            string str = o as string;
            Console.WriteLine("地址:" + str);
        }
        static void Main(string[] args)
        {
            Thread th = new Thread(download);
            th.Start("http://baidu.com");
            Console.WriteLine("main is completed");
        }

注意:使用as進行強制型別轉換 成功會正確輸出,失敗會輸出null。

以上資料傳輸的方法都是基於靜態變數進行傳輸的,但是定義過多靜態變數會導致多個執行緒存取同一個靜態變數,造成資源衝突。

靜態變數雖然方便存取,但是靜態的一般都是公共的,容易混亂。

4️⃣對Thread傳入一個無返回值多個引數的方法(定義一個結構體),但是不能用as強制轉換。

        public struct data
        {
            public string message;
            public int age;
        }
        static void download(object o)
        {
            data str = (data)o;//強制型別轉換
            Console.WriteLine("資訊:" + str.message);
            Console.WriteLine("年紀:" + str.age);
        }
        static void Main(string[] args)
        {
            data da = new data();
            da.message = "sss";
            da.age = 3;
            Thread th = new Thread(download);
            th.Start(da);
            Console.WriteLine("main is completed");
        }

由於結構體是值型別,不能為null,因此不能用as進行強制型別轉換。

5️⃣通過自定義類傳遞資料(即將通過執行緒呼叫一個類的成員方法)

先建立一個download類:

    class downLoad
    {
        public string URL { get; private set; }
        public string Message { get; private set; }
        //建構函式
        public downLoad(string uRL, string message)
        {
            URL = uRL;
            Message = message;
        }
        //下載方法
        public void  load()
        {
            Console.WriteLine("從" + URL + "獲取資訊:" + Message);
        }
    }

在主程式中將該類的成員方法傳入Thread中:

   static void Main(string[] args)
        {
            var download = new downLoad("www.baidu.com", "mp4");
            Thread th = new Thread(download.load);
            th.Start();
            Console.WriteLine("main is completed");
            Console.ReadKey();
        }


IT145.com E-mail:sddin#qq.com