2009-04-21 137 views
2

在c#中的程序中,我有2個線程與主線程分開。 當用戶關閉表單時,我想終止主線程中的一個線程。 我該如何去做呢?如果可能,請向我提供代碼。從另一個線程操作線程

回答

4

不要使用Thread.Abort作爲迄今爲止建議其他的答案,除非你希望你的程序處於未知狀態(見Ian GriffithsChris Sells更多信息的文章)。如果關閉表單實際上應該是在殺死應用程序,那麼你可能是可能是沒問題 - 但在這種情況下,我建議只使用後臺線程,當所有前臺線程終止時它都會自動死機。

從喬·達菲的"Concurrent Programming in Windows"

有些情況下,線程中止始終是安全的兩種情況:

  • 線程的主要目的中止是推倒在CLR 的AppDomain卸載線程。 [...]
  • 同步線程異常終止是安全的,只要調用者期望 從該方法拋出異常。 [...]

線程中止的所有其他用途充其量也是有問題的。 [...] 儘管線程中止在理論上比其他線程終止機制更安全,但它們仍然可能發生在不合時宜的時間,導致 不穩定和如果使用時不小心損壞。

(同步線程可放棄是當線程中止本身,而不是由另一個線程被中止。)

對於優美關閉(不冒着進入奇數狀態)使用,其被週期性地設置一個標誌從表單中檢查並從其他線程中檢查 - 考慮內存模型(例如,使標誌變爲揮發性,或者每次測試或設置時都使用鎖定)。以我的article on the topic爲例。

+0

要關閉表單,我有相應的事件。 我已經命名了我希望作爲SecondThread終止的線程。 但是我無法調用SecondThread.Is我在這裏失去了一些東西。 此外,如果有任何線程可以中止自己,將簡化事情,因爲我更喜歡使用標誌的概念,因爲你已經指出。 – Avik 2009-04-21 05:56:46

1

如果你想殺死你已經開始的線程,我會建議你持有一個對它的引用,如私人領域。當應用程序(或線程)完成時,您可以簡單地在該線程上調用Thread.Abort()

例如:

private Thread _myWorker; 

void doSomething() 
{ 
    _myWorker = new Thread(...); 
    _myWorker.Start(); 
} 

void killWorker() 
{ 
    _myWorker.Abort() 
} 

你應該注意到,然後調用Abort()線程上它會提高一個ThreadAbortException,你應該你的員工代碼中捕獲和處理,以清理等詳細信息請參見Thread.Abort

此外,當您的應用程序關閉其主線程(消息循環,又名Application.Run)時,子線程也將被關閉。

+0

子線程只會在後臺線程自動關閉。在主線程關閉後,前臺線程可以繼續運行。 – 2009-04-21 05:31:37

2

從其他線程殺死線程幾乎是總是一個壞主意。正確的方法是發信號通知終止,然後等待它。

這是因爲線程應該是儘可能可行自己的資源完全負責,這包括他們的一生。

它並不需要很複雜,一個簡單的變量,它可以被任何線程設置,並通過另一個線程讀取定期會做(這是不是真的在任何語言,但你應該明白我的意思,如果你知道C):

int exitThread1 = false; 
static void Thread1 (void) { 
    while (!exitThread1) { 
     // do stuff 
    } 
} 
static void mummyProc (void) { 
    int tid1 = startThread (Thread1); 
    // dum de dum de dum ... 
    exitThread1 = true; 
    joinThread (tid1); 
}