C# 創建線程的多種方式之Thread類基礎知識


1. Thread類創建線程

該類的構造函數可以接受ThreadStart委托參數(定義了無參,返回void的函數),以及ParameterizedThreadStart委托參數(定義了Object參數,返回void的函數)。

 

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread(Calculate);
            t1.Start(10);
            Console.WriteLine("Main is over");
            Console.ReadLine();
        }

        private static void Calculate(object obj)
        {
            int sum = 0;
            int total = (int)obj;
            for (int i = 0; i < total;i++ )
            {
                sum += i;
                Thread.Sleep(100);
            }
             Console.WriteLine("Sum is "+sum);
        }

 

當然Thread類也可以和Lamda表達式一起使用,實現與上面同樣的功能:

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread((obj) =>
            {
                int sum = 0;
                int total = (int)obj;
                for (int i = 0; i < total; i++)
                {
                    sum += i;
                    Thread.Sleep(100);
                }
                Console.WriteLine("Sum is " + sum);
            });
            t1.Start(10);
            Console.WriteLine("Main is over");
            Console.ReadLine();
        }

2. 后台線程

只要有一個前台在運行,應用進程就不會停止運行,而后台線程的運行則不會影響應用進程的結束,前,后台線程在線程優先級及其他方面並無差異。在默認情況下,Thread類創建的線程都是前台線程,也可以通過設置IsBackground屬性改變為后台線程,而線程池創建的均為后台線程。如下,將Console.ReadLine();指令禁用,運行發現控制台窗體不會馬上消失,而是會等待t1線程運行結束。

 

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread((obj) =>
            {
                int sum = 0;
                int total = (int)obj;
                for (int i = 0; i < total; i++)
                {
                    sum += i;
                    Thread.Sleep(100);
                }
                Console.WriteLine("Sum is " + sum);
            });
            t1.Start(10);
            Console.WriteLine("Main is over");
            //Console.ReadLine();
        }

 

3. 線程優先級

線程優先級用Priority屬性表示,定義的級別有Highest, AboveNormal, BelowNormal, Lowest, 操作系統會根據優先級去調度線程。如果有優先級相同的幾個線程在運行,就用得上時間量和循環的規則。如果線程是CPU密集型的(一直需要CPU不等待的),其優先級就低於定義的基本優先級。

4.線程的控制及狀態

 ThreadState 為線程定義了一組所有可能的執行狀態。一旦線程被創建,它就至少處於其中一個狀態中,直到終止。因為是各種狀態的組合,所以在判斷當前線程狀態的時候就需要用位運算,而不能簡單的使用等號(有個例外,Runing狀態值為0,所以用與運算不行)。

 Unstarted : 創建線程,但為調用Run();

 Runing: 調用Run()后,當線程正在被CPU調用;

WaitSleepJoin:線程等待,調用Sleep(), Join()會進入該狀態,其中Join()會阻塞當前線程,直到被調用線程運行結束或中止;

Stopped:線程運行結束后,進入該狀態,該狀態下無法通過Start(),重新啟動線程,必須重新創建線程;

Background:當線程的IsBackground屬性設置為true后,創建線程后調用線程前,狀態為Unstarted+Background,而調用線程后狀態為Runing+Background,sleep()后狀態為WaitSleepJoin+Background,線程結束后狀態為Stopped;

AbortRequested:當線程調用Abort(),處理完ThreadAbortException前,此時可以調用ResetAbort(),取消中止操作;

Aborted:當線程調用Abort(),處理完ThreadAbortException后;

SuspendRequested:當線程調用Suspend()后,線程被掛起前;

Suspended:線程已經被掛起,此時可用Resume(),繼續運行;

控制線程的常用函數在上面基本上已經提到,其中Suspend(), Resume()已經不推薦使用,因為線程掛起可能會造成一些不可預知的問題,例如線程死鎖,可以使用線程同步的一些類來代替使用。另外,Abort()也是不推薦使用的,可以定義布爾狀態量來代替使用。Interrupt()上面未提到,調用這個函數后,會出現InterruptException,接着喚醒處於WaitSleepJoin狀態的線程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM