1. 程式人生 > >開啟執行緒的幾種方式

開啟執行緒的幾種方式

目錄

執行緒開啟方式(一)-非同步委託 

        建立執行緒的一種簡單方式是定義一個委託,並非同步呼叫它。 委託是方法的型別安全的引用。Delegate類 還支援非同步地呼叫方法。在後臺,Delegate類會建立一個執行任務的執行緒。

    class Program
    {
        static int Test(int i, string str)
        {
            Console.WriteLine("test" + i + str);
            Thread.Sleep(100);//讓當前執行緒休眠(暫停執行緒的執行) 單位ms
            return 200;
        }
        static void Main(string[] args)
        {
            //在main執行緒中執行 一個執行緒裡面語句的執行 是從上到下的
            //1,通過委託 開啟一個執行緒
            Func<int, string, int> a = Test;
            IAsyncResult ar = a.BeginInvoke(30, "siki", null, null);// 開啟一個新的執行緒去執行 a所引用的方法 
            //IAsyncResult 可以取得當前執行緒的狀態
            //可以認為執行緒是同時執行的(非同步執行)
            Console.WriteLine("main");
            while (ar.IsCompleted == false)//如果當前執行緒沒有執行完畢
            {
                Console.Write(".");
                Thread.Sleep(10); //控制子執行緒的檢測頻率
            }
            int res = a.EndInvoke(ar);//取得非同步執行緒的返回值
            Console.WriteLine(res);

            Console .ReadKey ();
        }
    }

執行緒開啟方式(二)-Thread類

        我們構造一個thread物件的時候,可以傳遞一個靜態方法,也可以傳遞一個物件的普通方法。

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

       在這裡哪個先輸出是無法保證了執行緒的執行有作業系統決定,只能知道Main執行緒和分支執行緒是同步執行的。在這裡給Thread傳遞一個方法,呼叫Thread的Start方法,就會開啟一個執行緒去執行,傳遞的方法。

       給執行緒傳遞一些資料可以採用兩種方式,一種方式是使用帶ParameterizedThreadStart委託引數的Thread建構函式,一種方式是建立一個自定義的類,把執行緒的方法定義為例項方法,這樣就可以初始化例項的資料,之後啟動執行緒。

1)傳遞靜態方法

    class Program
    {
        static void DownloadFile()
        {
            Console.WriteLine("開始下載:"+Thread .CurrentThread .ManagedThreadId );
            //Thread .CurrentThread .ManagedThreadId 當前執行緒id
            Thread.Sleep(2000);
            Console.WriteLine("下載完成");

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動
            t.Start();//開始,開始去執行執行緒
            Console.WriteLine("Main");
            Console.ReadKey();
        }
    }

   還可以傳遞引數,方式1:

    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("開始下載:" +fileName );
            Thread.Sleep(2000);
            Console.WriteLine("下載完成");

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動
            t.Start("種子");//開始去執行執行緒 
            Console.WriteLine("下載中...");
            Console.ReadKey();
        }
    }

2)傳遞一個物件的普通方法

    class MyThread
    {
        private string filename;
        private string filepath;

        public MyThread(string fileName, string filePath)
        {
            this.filename = fileName;
            this.filepath = filePath;
        }

        public void DownFile()
        {
            Console.WriteLine("開始下載" + filename + filepath);
            Thread.Sleep(2000);
            Console.WriteLine("下載完成");
        }
    }
    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("開始下載:" +fileName );
            Thread.Sleep(2000);
            Console.WriteLine("下載完成");

        }
        static void Main(string[] args)
        {
            MyThread my = new MyThread("種子", "http://www.xxx.bbs");
            Thread t = new Thread(my.DownFile);
            t.Start();

            Console.ReadKey();
        }
    }

3)通過lambda表示式(委託引數的地方都可以使用Lambda表示式

    class Program
    {
        static void Main(string[] args)
        {
            //Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動
            Thread t = new Thread(() =>
            {
                Console.WriteLine("開始下載:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(2000);
                Console.WriteLine("下載完成");
            });
            t.Start();//開始,開始去執行執行緒
            Console.WriteLine("Main");
            Console.ReadKey();
        }
    }

執行緒開啟方式(三)-執行緒池  

        建立執行緒需要時間。 如果有不同的小任務要完成,就可以事先建立許多執行緒 , 在應完成這些任務時發出請求。 這個執行緒數最好在需要更多的執行緒時增加,在需要釋放資源時減少。

        不需要 自己建立執行緒池,系統已經有一個ThreadPool類管理執行緒。 這個類會在需要時增減池中執行緒的執行緒數,直到達到最大的執行緒數。 池中的最大執行緒數是可配置的。 在雙核 CPU中 ,預設設定為1023個工作執行緒和 1000個 I/o執行緒。也可以指定在建立執行緒池時應立即啟動的最小執行緒數,以及執行緒池中可用的最大執行緒數。 如果有更多的作業要處理,執行緒池中執行緒的個數也到了極限,最新的作業就要排隊,且必須等待執行緒完成其任務。

    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("執行緒開始:"+Thread .CurrentThread .ManagedThreadId  );
            Thread.Sleep(2000);
            Console.WriteLine("執行緒結束");

        }
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);

            Console.ReadKey();
        }
    }

執行緒開啟方式(四)-任務

    class Program
    {
        static void ThreadMethod()
        {
            Console.WriteLine("任務開始:");
            Thread.Sleep(2000);
            Console.WriteLine("任務結束");

        }
        static void Main(string[] args)
        {
            //Task t = new Task(ThreadMethod);
            //t.Start();也可以

            TaskFactory tf = new TaskFactory();
            tf.StartNew(ThreadMethod);

            Console.WriteLine("main");
            Console.ReadKey();
        }
    }