執行緒同步處理
更新:2007 年 11 月
當您撰寫執行緒應用程式時,您可能需要將個別執行緒與程式的其他部分進行同步處理。同步是多執行緒程式設計的非結構化本質與同步處理的結構順序之間的折衷方式。
您可以使用同步技術:
在工作必須以特定的順序執行時,明確地控制程式碼執行的順序。
-或-
防止兩個執行緒同時共用一個資源時發生問題。
例如,您可以使用同步處理讓顯示程序等待,直到在另一個執行緒上執行的資料擷取程序完成為止。
同步技術
同步處理的方法有兩種:輪詢和使用同步物件。如需同步物件的詳細資訊,請參閱進階同步技術。
輪詢
輪詢會重複檢查迴圈內非同步呼叫的狀態。輪詢是管理執行緒最沒有效率的方法,因為它會重複檢查各種執行緒屬性而浪費資源。
例如,在輪詢時可使用 IsAlive 屬性以檢查執行緒是否存在。使用這個屬性時請小心,因為存留的執行緒並不一定執行。
您可以使用執行緒的 ThreadState 屬性,取得執行緒狀態更詳細的資訊。由於執行緒在任何指定時間內可處於一種以上的狀態,因此儲存在 ThreadState 中的值可能會是 System.Threading.ThreadState 列舉型別中多種值的組合。因此,當輪詢時您應該小心檢查所有相關的執行緒狀態。例如,如果執行緒狀態指出它的狀態不是 Running,則它可能已經完成。另一方面,它可能是暫停或休眠。
等候執行緒完成
如果要判斷執行緒是否在開始另一個工作之前已完成,Thread.Join 方法是相當有用的。Join 方法會等候一段指定的時間,以便讓執行緒結束。如果執行緒在逾時之前結束,則 Join 會傳回 True,否則會傳回 False。
如您所想,輪詢會犧牲許多多執行緒的優點以控制執行緒執行的順序。由於輪詢是如此沒有效率,因此一般不建議使用輪詢。更有效率的處理方法是使用 Join 方法控制執行緒。Join 會讓呼叫程序等候,直到執行緒完成,或者如果指定了逾時,則會直到呼叫逾時為止。"join" 這個名稱所根據的想法是:建立新執行緒是執行路徑中的分支。您可以使用 Join,將個別的執行路徑再次合併到單一執行緒。
圖 1 執行緒
有一點應該明白:Join 是同步或「封鎖」呼叫。一旦您呼叫 Join 或等候控制代碼的等候方法,呼叫程序即會停止,並等待執行緒發出它已完成的信號。
Sub JoinThreads()
Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)
Thread1.Start()
Thread1.Join() ' Wait for the thread to finish.
MsgBox("Thread is done")
End Sub
Sub SomeTask()
' Insert code to perform a task here.
End Sub
這些控制執行緒的簡單方法 (在管理少量執行緒時很有用) 難以用在大型專案中。進階同步技術將會討論可用於同步處理執行緒的一些技巧。