共用方式為


多執行緒應用程式 (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);

啟動和停止執行緒

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

newThread.Start()
newThread.Start();

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

newThread.Abort()
newThread.Abort();

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

執行緒方法

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

方法

動作

Start

讓執行緒開始執行。

Sleep

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

Suspend

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

Abort

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

Resume

重新啟動暫停的執行緒。

Join

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

安全點

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

執行緒屬性

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

屬性

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# 建立執行緒