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狀態的線程。