2010-05-17 106 views
15

我有一個應用程序在單獨的Thread中執行一些後臺任務(網絡偵聽&讀取)。但是,當我關閉應用程序時(單擊標題欄上的「x」按鈕),線程似乎沒有被終止/中止。 是因爲主線程程序是while(true) {...}? 這裏有什麼解決方案?我正在尋找線程的「中斷」標誌作爲「while」循環的條件,但沒有找到任何標誌。線程不會在應用程序關閉時中止

回答

21

最簡單的方法是將線程的IsBackground屬性設置爲true。這將阻止它保持應用程序的開放。當所有非後臺線程終止時,應用程序終止。

停止線程的更可控制的方法是發送一條消息,使其乾淨地關閉並確保它在終止主線程之前終止。

我不推薦的方法是致電Thread.Abort。這有一些問題,其中之一是它不能保證終止線程。從文檔:

調用此方法通常終止線程。

強調我的。

+1

+1消息方法。'while(stayAlive)'而不是'true'會更乾淨,即使循環可能需要幾秒鐘時間才能清除。 – user7116 2010-05-17 21:58:43

0

好,而不是while(true),也許你應該:

while(appIsRunning) 
{ 
} 

而且,在你的形式結束活動,

appIsRunning = false; 
thread.Join(2000); 

在最後一行是隻是爲了確保您等待線程乾淨地完成。還有很多其他的方法可以強制結束一個線程,但問題就在那裏:你不希望成爲,你希望它們儘可能自然地發生。

加入後,您可以檢查線程的狀態以查看它是否已完成。如果不是,然後(並且只有這樣)纔會強制終止並且可能會通知您的用戶(或寫入日誌記錄)某些事情沒有按照應有的方式結束。

+0

是的,但請記住使用'volatile'或'lock'或其他一些同步方法。 – 2010-05-17 21:57:05

+0

@Mark:這裏可能是完全錯誤的,但是由於子線程只讀取並且主線程只寫入,是否有機會出現錯誤? – 2010-05-17 22:42:16

+1

如果不同步,則不保證在另一個線程中可以看到一個線程的appIsRunning更改。你可以在這裏閱讀更多:http://timl.net/2009/03/volatile-memory.html – 2010-05-17 22:46:54

1

你可以提高從標識符名稱,而(真)環路

void DoWork() { 
    while(!ShouldIQuitManualResetEvent.WaitOne(0)) { 
     // do something 
    } 
    IDidQuitManualResetEvent.Set() 
} 

更優雅一點,短。

3

您可以隨時生效的問題:

class Program 
{ 
    public static void Main() 
    { 
     // ... do stuff 
     Environment.Exit(Environment.ExitCode); 
    } 
} 

更好的方法是馬克已經提到的Thread.IsBackground屬性設置爲true。

0

您就可以開始您的主題:

ThreadPool.QueueUserWorkItem(DoStuff, input) 

而且它會隨着應用程序關閉自動中止。

相關問題