目錄
一、線程的定義
二、線程的基礎知識
三、以ThreadStart方式實作多線程
四、CLR線程池的工作者線程
五、CLR線程池的I/O線程
六、異步 SqlCommand
七、并行程式設計與PLINQ
八、計時器與鎖
2.1 System.Threading.Thread類
System.Threading.Thread是用于控制線程的基礎類,通過Thread可以控制目前應用程式域中線程的建立、挂起、停止、銷毀。
它包括以下常用公共屬性:
屬性名稱 | 說明 |
---|---|
CurrentContext | 擷取線程正在其中執行的目前上下文。 |
CurrentThread | 擷取目前正在運作的線程。 |
ExecutionContext | 擷取一個 ExecutionContext 對象,該對象包含有關目前線程的各種上下文的資訊。 |
IsAlive | 擷取一個值,該值訓示目前線程的執行狀态。 |
IsBackground | 擷取或設定一個值,該值訓示某個線程是否為背景線程。 |
IsThreadPoolThread | 擷取一個值,該值訓示線程是否屬于托管線程池。 |
ManagedThreadId | 擷取目前托管線程的唯一辨別符。 |
Name | 擷取或設定線程的名稱。 |
Priority | 擷取或設定一個值,該值訓示線程的排程優先級。 |
ThreadState | 擷取一個值,該值包含目前線程的狀态。 |
2.1.1 線程的辨別符
ManagedThreadId 是确認線程的唯一辨別符,程式在大部分情況下都是通過Thread.ManagedThreadId來辨識線程的。而Name是一個可變值,在預設時 候,Name為一個空值 Null,開發人員可以通過程式設定線程的名稱,但這隻是一個輔助功能。
2.1.2 線程的優先級别
.NET為線程設定了Priority屬性來定義線程執行的優先級别,裡面包含5個選項,其中Normal是預設值。除非系統有特殊要求,否則不應該随便設定線程的優先級别。
成員名稱 | |
---|---|
Lowest | 可以将 Thread 安排在具有任何其他優先級的線程之後。 |
BelowNormal | 可以将 Thread 安排在具有 Normal 優先級的線程之後,在具有 Lowest 優先級的線程之前。 |
Normal | 預設選擇。可以将 Thread 安排在具有 AboveNormal 優先級的線程之後,在具有 BelowNormal 優先級的線程之前。 |
AboveNormal | 可以将 Thread 安排在具有 Highest 優先級的線程之後,在具有 Normal 優先級的線程之前。 |
Highest | 可以将 Thread 安排在具有任何其他優先級的線程之前。 |
2.1.3 線程的狀态
通過ThreadState可以檢測線程是處于Unstarted、Sleeping、Running 等等狀态,它比 IsAlive 屬性能提供更多的特定資訊。
前面說過,一個應用程式域中可能包括多個上下文,而通過CurrentContext可以擷取線程目前的上下文。
CurrentThread是最常用的一個屬性,它是用于擷取目前運作的線程。
2.1.4 System.Threading.Thread的方法
Thread 中包括了多個方法來控制線程的建立、挂起、停止、銷毀,以後來的例子中會經常使用。
方法名稱 | |
---|---|
Abort() | 終止本線程。 |
GetDomain() | 傳回目前線程正在其中運作的目前域。 |
GetDomainId() | 傳回目前線程正在其中運作的目前域Id。 |
Interrupt() | 中斷處于 WaitSleepJoin 線程狀态的線程。 |
Join() | 已重載。 阻塞調用線程,直到某個線程終止時為止。 |
Resume() | 繼續運作已挂起的線程。 |
Start() | 執行本線程。 |
Suspend() | 挂起目前線程,如果目前線程已屬于挂起狀态則此不起作用 |
Sleep() | 把正在運作的線程挂起一段時間。 |
2.1.5 開發執行個體
以下這個例子,就是通過Thread顯示目前線程資訊
1 static void Main(string[] args)
2 {
3 Thread thread = Thread.CurrentThread;
4 thread.Name = "Main Thread";
5 string threadMessage = string.Format("Thread ID:{0}\n Current AppDomainId:{1}\n "+
6 "Current ContextId:{2}\n Thread Name:{3}\n "+
7 "Thread State:{4}\n Thread Priority:{5}\n",
8 thread.ManagedThreadId, Thread.GetDomainID(), Thread.CurrentContext.ContextID,
9 thread.Name, thread.ThreadState, thread.Priority);
10 Console.WriteLine(threadMessage);
11 Console.ReadKey();
12 }
運作結果

2.2 System.Threading 命名空間
在 System.Threading命名空間内提供多個方法來建構多線程應用程式,其中ThreadPool與Thread是多線程開發中最常用到的, 在.NET中專門設定了一個CLR線程池專門用于管理線程的運作,這個CLR線程池正是通過ThreadPool類來管理。而Thread是管理線程的最 直接方式,下面幾節将詳細介紹有關内容。
類 | |
AutoResetEvent | 通知正在等待的線程已發生事件。無法繼承此類。 |
管理目前線程的執行上下文。無法繼承此類。 | |
Interlocked | 為多個線程共享的變量提供原子操作。 |
Monitor | 提供同步對對象的通路的機制。 |
Mutex | 一個同步基元,也可用于程序間同步。 |
Thread | 建立并控制線程,設定其優先級并擷取其狀态。 |
ThreadAbortException | 在對 Abort 方法進行調用時引發的異常。無法繼承此類。 |
ThreadPool | 提供一個線程池,該線程池可用于發送工作項、處理異步 I/O、代表其他線程等待以及處理計時器。 |
Timeout | 包含用于指定無限長的時間的常數。無法繼承此類。 |
Timer | 提供以指定的時間間隔執行方法的機制。無法繼承此類。 |
WaitHandle | 封裝等待對共享資源的獨占通路的作業系統特定的對象。 |
在System.Threading中的包含了下表中的多個常用委托,其中ThreadStart、ParameterizedThreadStart是最常用到的委托。
由ThreadStart生成的線程是最直接的方式,但由ThreadStart所生成并不受線程池管理。
而ParameterizedThreadStart是為異步觸發帶參數的方法而設的,在下一節将為大家逐一細說。
委托 | |
---|---|
ContextCallback | 表示要在新上下文中調用的方法。 |
ParameterizedThreadStart | 表示在 Thread 上執行的方法。 |
ThreadExceptionEventHandler | 表示将要處理 Application 的 ThreadException 事件的方法。 |
ThreadStart | |
TimerCallback | 表示處理來自 Timer 的調用的方法。 |
WaitCallback | 表示線程池線程要執行的回調方法。 |
WaitOrTimerCallback | 表示當 WaitHandle 逾時或終止時要調用的方法。 |
2.3 線程的管理方式
通 過ThreadStart來建立一個新線程是最直接的方法,但這樣建立出來的線程比較難管理,如果建立過多的線程反而會讓系統的性能下載下傳。有見及 此,.NET為線程管理專門設定了一個CLR線程池,使用CLR線程池系統可以更合理地管理線程的使用。所有請求的服務都能運作于線程池中,當運作結束時 線程便會回歸到線程池。通過設定,能控制線程池的最大線程數量,在請求超出線程最大值時,線程池能按照操作的優先級别來執行,讓部分操作處于等待狀态,待 有線程回歸時再執行操作。