多執行緒應用程式 (C# 和 Visual Basic)

使用 Visual Basic 和 C#,您就可以撰寫能夠同時執行多個工作的應用程式。可能妨礙其他工作的工作可以在個別執行緒上執行,這也就是名為「多執行緒」(Multithreading) 或「無限制執行緒」(Free Threading) 的處理序。

使用多執行緒的應用程式較能回應使用者輸入,因為當佔用大量處理器資源的工作在個別執行緒上執行時,使用者介面還是保持作用中的狀態。當您建立可擴充的應用程式時,多執行緒也相當有用,因為您可以隨著工作量的增加來加入執行緒。

注意事項注意事項

Visual Studio 2010 和 .NET Framework 4 提供了新的執行階段、新的類別庫型別和新的診斷工具,以加強支援平行程式設計。如需詳細資訊,請參閱以 .NET Framework 進行平行程式設計

使用 BackgroundWorker 元件

建立多執行緒應用程式的最可靠方式是使用 BackgroundWorker 元件。這個類別會管理專門用於處理您所指定之方法的不同執行緒。如需範例,請參閱逐步解說:使用 BackgroundWorker 元件進行多執行緒處理 (C# 和 Visual Basic)

若要在背景開始作業,請建立 BackgroundWorker,並接聽用於報告作業進度,以及在作業完成時發出信號的事件。您可以用程式設計方式建立 BackgroundWorker 物件,或將它從 [工具箱] 的 [元件] 索引標籤中拖曳到表單。如果在 [表單設計工具] 中建立 BackgroundWorker,則此元件會出現在 [元件匣] 中,且它的屬性會顯示在 [屬性] 視窗中。

設定背景作業

若要設定背景作業,請加入 DoWork 事件的事件處理常式。在這個事件處理常式中呼叫耗時作業。

若要啟動作業,請呼叫 RunWorkerAsync。若要接收進度更新的告知,請處理 ProgressChanged 事件。若要在作業完成時接收告知,請處理 RunWorkerCompleted 事件。

因為是在呼叫 RunWorkerAsync 方法的執行緒上引發 ProgressChangedRunWorkerCompleted 事件,所以處理那些事件的方法可以存取應用程式的使用者介面。然而,因為 DoWork 事件處理常式是在背景執行緒中執行,所以它無法與任何使用者介面物件搭配使用。

建立和使用執行緒

如果需要更加控制應用程式執行緒的行為,您可以自己管理這些執行緒。但是請注意,撰寫正確的多執行緒應用程式十分困難:應用程式可能會停止回應或因競爭情況而發生暫時性 (Transient) 錯誤。如需詳細資訊,請參閱安全執行緒的元件

透過宣告 Thread 型別的變數,並呼叫建構函式,提供您要在新執行緒上執行之程序或方法的名稱,即可建立新的執行緒。下列程式碼提供一個範例。

Dim newThread As New System.Threading.Thread(AddressOf AMethod)
System.Threading.Thread newThread =
    new System.Threading.Thread(AMethod);

ck8bc5c6.collapse_all(zh-tw,VS.110).gif啟動和停止執行緒

若要啟動新執行緒的執行,請使用 Start 方法,如下列程式碼所示。

newThread.Start()
newThread.Start();

若要停止執行緒的執行,請使用 Abort 方法,如下列程式碼所示。

newThread.Abort()
newThread.Abort();

除了啟動和停止執行緒之外,也可以呼叫 SleepSuspend 方法以暫停執行緒、使用 Resume 方法以繼續暫停的執行緒,以及使用 Abort 方法以終結執行緒。

ck8bc5c6.collapse_all(zh-tw,VS.110).gif執行緒方法

下表列出一些您可用來控制個別執行緒的方法。

方法

動作

Start

讓執行緒開始執行。

Sleep

暫停執行緒一段指定的時間。

Suspend

當執行緒到達安全點時暫停執行緒。

Abort

當執行緒到達安全點時停止執行緒。

Resume

重新啟動暫停的執行緒。

Join

讓目前的執行緒等待另一個執行緒完成。如果與逾時值搭配使用,而執行緒在指定時間內完成,則這個方法會傳回 True。

ck8bc5c6.collapse_all(zh-tw,VS.110).gif安全點

這些方法大部分是自我闡明,但「安全點」(Safe Point) 對您而言可能是新的概念。對 Common Language Runtime 而言,安全點是在程式碼中能安全執行自動「記憶體回收」(Garbage Collection) 的位置,記憶體回收是一個釋放未使用的變數並重新利用記憶體的處理序。呼叫執行緒的 AbortSuspend 方法時,Common Language Runtime 會分析程式碼並判斷停止執行執行緒的適當位置。

ck8bc5c6.collapse_all(zh-tw,VS.110).gif執行緒屬性

執行緒也包含數個有用的屬性,如下表所示:

屬性

IsAlive

如果執行緒在作用中,則包含值 True。

IsBackground

取得或設定指示執行緒是否是或應該是背景執行緒的布林值。背景執行緒就像前景執行緒一樣,但背景執行緒不能避免處理序停止。一旦停止所有屬於處理序的前景執行緒,Common Language Runtime 會針對執行中之背景執行緒呼叫 Abort 方法以結束處理序。

Name

取得或設定執行緒的名稱。最常用於在偵錯時探索個別執行緒。

Priority

取得或設定作業系統用來設定執行緒排程之優先權的值。

ApartmentState

取得或設定特定執行緒所使用的執行緒模型。執行緒模型在執行緒呼叫 Unmanaged 程式碼時很重要。

ThreadState

包含描述執行緒狀態的值。

執行緒優先權

每個執行緒都具有優先權屬性,用於判斷它有多少處理器時間執行。作業系統會配置較長的時間給高優先權執行緒,而配置較短的時間給低優先權執行緒。新執行緒是使用值 Normal 建立的,但是您可以將 Priority 屬性變更為 ThreadPriority 列舉中的任何值。

如需各種執行緒優先權的詳細描述,請參閱 ThreadPriority

前景和背景執行緒

「前景執行緒」(Foreground Thread) 永遠是處於執行的狀態,而「背景執行緒」(Background Thread) 則會在最後一個前景執行緒停止時結束。您可以使用 IsBackground 屬性,判斷或變更執行緒的背景狀態。

在表單和控制項使用多執行緒

儘管多執行緒最適用於執行程序與類別方法 (Class Method),但您也可以將它使用在表單及控制項。如果您要這麼做,請注意下列幾點:

  • 盡量只在用來建立控制項的執行緒上執行控制項的方法。如果您必須從另一個執行緒呼叫控制項的方法,則必須使用 Invoke 呼叫方法。

  • 請不要使用 SyncLock (Visual Basic) 或 lock (C#) 陳述式,來鎖定操作控制項或表單的執行緒。由於控制項和表單的方法有時會回呼至呼叫程序,因此最後可能會不慎產生死結 (Deadlock),在這個情況下,兩執行緒會等候彼此釋放鎖定,而使得應用程式中止。

請參閱

參考

執行緒同步處理 (C# 和 Visual Basic)

Invoke

InvokeRequired

Thread

概念

多執行緒程序的參數和傳回值 (C# 和 Visual Basic)

其他資源

元件中的多執行緒

HOW TO:使用 Visual C# 建立執行緒