c# 創建、終止線程


該示例創建一個名為
Worker 的類,該類包含輔助線程將執行的方法 DoWork。這實際上是輔助線程的 Main 函數。輔助線程將通過調用此方法來開始執行,並在此方法返回時自動終止。DoWork 方法如下所示:

Worker 類包含另一個方法,該方法用於通知
DoWork 它應當返回。此方法名為 RequestStop,如下所示:

RequestStop 方法只是將
true 賦給 _shouldStop 數據成員。由於此數據成員由 DoWork 方法來檢查,因此這會間接導致
DoWork 返回,從而終止輔助線程。但是,需要注意:DoWorkRequestStop 將由不同線程執行。DoWork 由輔助線程執行,而
RequestStop 由主線程執行,因此 _shouldStop 數據成員聲明為 volatile,如下所示:

volatile 關鍵字用於通知編譯器,將有多個線程訪問
_shouldStop 數據成員,因此它不應當對此成員的狀態做任何優化假設。有關更多信息,請參見 volatile(C# 參考)。

通過將
volatile_shouldStop 數據成員一起使用,可以從多個線程安全地訪問此成員,而不需要使用正式的線程同步技術,但這僅僅是因為
_shouldStopbool。這意味着只需要執行單個原子操作就能修改 _shouldStop。但是,如果此數據成員是類、結構或數組,那么,從多個線程訪問它可能會導致間歇的數據損壞。假設有一個更改數組中的值的線程。Windows 定期中斷線程,以便允許其他線程執行,因此線程會在分配某些數組元素之后和分配其他元素之前被中斷。這意味着,數組現在有了一個程序員從不想要的狀態,因此,讀取此數組的另一個線程可能會失敗。

在實際創建輔助線程之前,Main 函數會創建一個
Worker 對象和 Thread 的一個實例。線程對象被配置為:通過將對 Worker.DoWork 方法的引用傳遞給
Thread
構造函數,來將該方法用作入口點,如下所示:

此時,盡管輔助線程對象已存在並已配置,但尚未創建實際的輔助線程。只有當
Main 調用 Start 方法后,才會創建實際的輔助線程:

此時,系統將啟動輔助線程的執行,但這是在與主線程異步執行的。這意味着
Main 函數將在輔助線程進行初始化的同時繼續執行代碼。為了保證 Main 函數不會嘗試在輔助線程有機會執行之前將它終止,Main 函數將一直循環,直到輔助線程對象的 IsAlive 屬性設置為
true

下一步,通過調用 Sleep 來將主線程中斷片刻。這保證了輔助線程的
DoWork 函數在 Main 函數執行其他任何命令之前,在 DoWork 方法內部執行若干次循環:

在 1 毫秒之后,Main 將通知輔助線程對象,它應當使用
Worker.RequestStop 方法(前面已介紹)自行終止:

還可以通過調用 Abort 來從一個線程終止另一個線程,但這會強行終止受影響的線程,而不管它是否已完成自己的任務,並且不提供清理資源的機會。此示例中顯示的技術是首選方法。

最后,Main 函數對輔助線程對象調用 Join 方法。此方法導致當前線程阻塞或等待,直到對象所表示的線程終止。因此,直到輔助線程返回后,Join 才會返回,然后自行終止:

此時,只有執行
Main 的主線程還存在。它會顯示一條最終消息,然后返回,從而使主線程也終止。

下面顯示了完整的示例:

示例

示例輸出

main thread: starting worker thread... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: working... worker thread: terminating gracefully... main thread: worker thread has terminated


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM