C# 多執行緒學習(2) :如何操縱一個執行緒

發表於2015-10-08

下面我們就動手來建立一個執行緒,使用Thread類建立執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒幹什麼事)

在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的,你可以把ThreadStart理解為一個函式指標,指向執行緒要執行的函式,當呼叫Thread.Start()方法後,執行緒就開始執行ThreadStart所代表或者說指向的函式。

開啟你的VS.net,新建一個控制檯應用程式(Console Application),編寫完全控制一個執行緒的程式碼示例:

這段程式包含兩個類Alpha和Simple,在建立執行緒oThread時我們用指向Alpha.Beta()方法的初始化了ThreadStart代理(delegate)物件,當我們建立的執行緒oThread呼叫oThread.Start()方法啟動時,實際上程式執行的是Alpha.Beta()方法:

然後在Main()函式的while迴圈中,我們使用靜態方法Thread.Sleep()讓主執行緒停了1ms,這段時間CPU轉向執行執行緒oThread。然後我們試圖用Thread.Abort()方法終止執行緒oThread,注意後面的oThread.Join(),Thread.Join()方法使主執行緒等待,直到oThread執行緒結束。你可以給Thread.Join()方法指定一個int型的引數作為等待的最長時間。之後,我們試圖用Thread.Start()方法重新啟動執行緒oThread,但是顯然Abort()方法帶來的後果是不可恢復的終止執行緒,所以最後程式會丟擲ThreadStateException異常。

 

主執行緒Main()函式

所有執行緒都是依附於Main()函式所在的執行緒的,Main()函式是C#程式的入口,起始執行緒可以稱之為主執行緒。
如果所有的前臺執行緒都停止了,那麼主執行緒可以終止,而所有的後臺執行緒都將無條件終止。

所有的執行緒雖然在微觀上是序列執行的,但是在巨集觀上你完全可以認為它們在並行執行。

 

Thread.ThreadState 屬性

這個屬性代表了執行緒執行時狀態,在不同的情況下有不同的值,我們有時候可以通過對該值的判斷來設計程式流程。

ThreadState 屬性的取值如下:

  • Aborted:執行緒已停止;
  • AbortRequested:執行緒的Thread.Abort()方法已被呼叫,但是執行緒還未停止;
  • Background:執行緒在後臺執行,與屬性Thread.IsBackground有關;
  • Running:執行緒正在正常執行;
  • Stopped:執行緒已經被停止;
  • StopRequested:執行緒正在被要求停止;
  • Suspended:執行緒已經被掛起(此狀態下,可以通過呼叫Resume()方法重新執行);
  • SuspendRequested:執行緒正在要求被掛起,但是未來得及響應;
  • Unstarted:未呼叫Thread.Start()開始執行緒的執行;
  • WaitSleepJoin:執行緒因為呼叫了Wait(),Sleep()或Join()等方法處於封鎖狀態;

上面提到了Background狀態表示該執行緒在後臺執行,那麼後臺執行的執行緒有什麼特別的地方呢?其實後臺執行緒跟前臺執行緒只有一個區別,那就是後臺執行緒不妨礙程式的終止。一旦一個程式所有的前臺執行緒都終止後,CLR(通用語言執行環境)將通過呼叫任意一個存活中的後臺程式的Abort()方法來徹底終止程式。

 

執行緒的優先順序

當執行緒之間爭奪CPU時間時,CPU 是按照執行緒的優先順序給予服務的。在C#應用程式中,使用者可以設定5個不同的優先順序,由高到低分別是Highest,AboveNormal,Normal,BelowNormal,Lowest,在建立執行緒時如果不指定優先順序,那麼系統預設為ThreadPriority.Normal。

給一個執行緒指定優先順序,我們可以使用如下程式碼:

通過設定執行緒的優先順序,我們可以安排一些相對重要的執行緒優先執行,例如對使用者的響應等等。

相關文章