2008-08-16 68 views
6

嘗試重新啓動線程時,我經常會遇到System.Threading.ThreadStateException。有問題的代碼如下:嘗試重新啓動線程時發生ThreadStateException

// Make sure the thread is done stopping 
while (this.mThread.ThreadState == ThreadState.Running) 
{ 
    Thread.Sleep(0); 
} 
// Respawn a thread if the current one is stopped or doesn't exist 
if (this.mThread == null || this.mThread.ThreadState == ThreadState.Stopped) 
{ 
    this.mThread = new Thread(new ParameterizedThreadStart(Monitor)); } 
// Start the thread 
if (check) 
{ 
    this.mThread.Start(60000); 
} 
else 
{ 
    this.mThread.Start(0); 
} 

所以兩個問題 - 這是做事的正確方法,它是,有沒有辦法來防止錯誤的發生?

回答

3

的問題是,你有代碼,首先檢查它是否應該創建一個新的線程對象,另一段代碼,確定閹啓動線程對象。由於競爭條件和類似的事情,你的代碼可能最終試圖調用。開始一個現有的線程對象。考慮到您不會在檢查變量後發佈詳細信息,因此無法知道可能會觸發此行爲。

您應該重新組織代碼,以保證.Start保證只在新對象上被調用。簡而言之,您應該將Start方法放入與創建新線程對象相同的if語句中。

就個人而言,我會嘗試重新整理整個代碼,所以我並不需要創建另一個線程,但包裝線程對象中的代碼迴路內部,使得線程只是不斷去。

1

由於您試圖啓動不處於可啓動狀態的線程,因此拋出了ThreadStateException。最有可能的情況是它已經在運行,或者它已經完全退出。

可能有一些事情可能發生。首先,線程可能已經從Running轉換到StopRequested,但尚未完全停止,所以您的邏輯不會創建新線程,並且您嘗試啓動剛完成運行或即將運行的線程完成運行(兩者都不是用於重新啓動的有效狀態)。

另一種可能性是該線程被中止。中止的線程進入中止狀態,而不是停止狀態,當然也不適用於重新啓動。

真的,唯一的一種線程的是還活着,可以「重新開始」是一個已暫停。您可能要改用此條件:

if (this.mThread == null || this.mThread.ThreadState != ThreadState.Suspended)

6

有可能一個線程在一個以上的國家一下子所以的ThreadState屬性實際上是可能的狀態的位圖。因此,只有一個國家的平等測試不會給你正確的結果。你需要做的是這樣的:

if((mThread.ThreadState & ThreadState.Running) != 0) 

然而,檢查線程狀態是錯誤做任何事情。我並不完全清楚你想達到什麼目的,但我會猜測你在等待線程在重新啓動之前終止。在這種情況下,你應該做的:

mThread.Join(); 
mThread = new Thread(new ParameterizedThreadStart(Monitor)); 
if(check) 
    mThread.Start(60000); 
else 
    mThread.Start(0); 

但如果你描述你想更詳細地解決我幾乎可以肯定這個問題會有一個更好的解決方案。等待一個線程結束只是重新啓動它似乎不是對我有效。也許你只是需要某種線程間通信?

John。

相關問題