2013-01-05 103 views
0

我有一個線程,我試圖停止。我所做的是以下幾點。停止我的線程

randomImages = new Thread(new ThreadStart(this.chooseRandomImage)); 
      randomImages.Start(); 

這是在單擊停止線扣我簡單地設置threadAlive成假線程

bool threadAlive = true; 
public void chooseRandomImage() 
    { 
     while(threadAlive) 
     { 
      try 
      { 
       //do stuff 


      } 

      catch (Exception exe) 
      { 
       MessageBox.Show(exe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 


     } 
    } 

現在,調用的方法。 問題是線程不會立即停止,就好像它已經聚集了一種勢頭。 如何立即停止線程,並可能重新啓動它?

private void butStopThread_Click(object sender, EventArgs e) 
    { 

     threadAlive = false; 


     if(threadAlive == false) 
     { 
      //do stuff 
     } 


    } 
+0

在這個問題中有很多選項[如何等待線程完成與.NET?](http:// stackoverflow。com/questions/1584062 /如何等待線程結束與網絡) – Steve

+1

@Steve我很確定,大多數不知道意大利語的人不熟悉* elencated *的含義。只是在說'。 –

+0

是啊,列出的上市....哦,我的...我需要一點糖給大腦。是時候吃午飯了 – Steve

回答

2

對不起,這是做的最好的方式。使用.NET 4.0向上,你應該使用任務,而不是線程,然後有一個名爲CancellationToken的東西,它和你的變量差不多。

然後,取消之後,您等待處理完成。如果這需要快速發生,那麼 - 好 - 檢查更爲精細的取消,即更頻繁地檢查。

正如在http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation中所解釋的那樣,中止線程可能有重大的副作用 - 這就是爲什麼該方法通常不應該使用。

而且,停止的線程等不能以神奇的方式重新啓動 - 您必須將其放入邏輯(重新啓動點,保存點,長時間運行的事務,記住它完成的位置)。作爲一個旁註 - 如果你堅持不使用任務並且可以訪問.NET的最新版本,如果你使用Interlocked訪問類方法,那麼它就不需要Volatile,而這個方法以前是一些線程安全的彙編指令每個定義。

1

有可能終止從另一個線程的線程與呼叫 中止,但這種強行終止受影響的線程,但不 關心它是否已經完成了它的任務,並沒有提供 機會的清理資源。該示例中示出的技術是優選的。

您需要使用Abort method但不建議

+1

-1。 Whow。另一個。看,有一個原因是在後續版本中被標記爲「不要使用」。請查看http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation獲取解釋 - 這是一種您不應該打電話的方法。它可能有嚴重的副作用。 – TomTom

0

從您提供的信息看來, threadAlive變量正在被工作線程和UI線程訪問。嘗試使用volatile關鍵字來聲明threadAlive,以確保在沒有同步問題的情況下進行跨線程訪問。

volatile bool threadAlive; 

要重新啓動線程,首先需要確保它執行所有必要的清理。在主/ UI線程的線程對象上使用Join方法調用,以確保您的線程安全終止。要重新啓動,只需調用線程上的Start方法即可。

randomImages.Join(); 
+0

他已經擁有它作爲易變(如你可以在他的帖子中看到)。他只是不想讓線程完成。 – TomTom

+0

那麼我看不到在原始帖子中使用volatile關鍵字聲明的threadAlive變量。你能指出嗎? :) 此外,他希望線程立即停止。然後重新啓動它。我的答案只是允許這樣做。 – prthrokz

+0

Ups。忽略了這一點。是。抱歉。我很抱歉。但從技術上講,它不能是一個易變的,你可以使用互鎖訪問。 – TomTom