2011-02-14 148 views
8

需要幫助來停止BackgroundWorker線程。 我想停止後臺工作線程。這是我在做什麼:需要幫助來停止BackgroundWorker線程

在停止按鈕點擊(UI層):

if (backgroundWorker.IsBusy == true && 
    backgroundWorker.WorkerSupportsCancellation == true) 
{ 
    backgroundWorker.CancelAsync(); 
} 

在DoWork的事件(UI層):

if ((backgroundWorker.CancellationPending == true)) 
{ 
    e.Cancel = true; 
} 
else 
{ 
    //Function which progresses the progress bar is called 
    //here with its definition in business layer 
} 

一旦DoWork的事件被觸發,我程序控制是在業務層定義的函數中,我如何恢復到DoWork事件來設置'e.Cancel = true'?

回答

2

DoWork將在它自己的線程中運行並且不依賴於GUI線程。

你幾乎一切正確。在GUI線程中,將CancellationPending設置爲true

DoWork方法中,您可能有某種類型的循環。

這裏您檢查是否CancellationPending == true,但除了將e.Cancel設置爲true之外,還包括return調用,以使該方法返回並有效地停止該工作。這也會導致WorkerCompleted事件在GUI線程上觸發,如果該方法被連接。

如果DoWork方法進行一些長期的任務,不分成部分(例如,如果您DoWork方法是這樣的:

void DoWork((object sender, DoWorkEventArgs e) 
{ 
    myClass.SomeLongOperation(); 
} 

那麼你的運氣了,因爲你需要手動檢查CancellationPendingDoWork方法裏面能夠阻止它。如果DoWork本身從GUI設置CancellationPending「掛起」和你無法控制一個操作等待,你不能阻止它(在任何有序的方式)線程。

+1

。如果您>在DoWork中沒有循環,那麼它不會工作。 – stuartd

+1

@Stuart - 正如答案中所述,這是正確的。如果沒有循環,沒有強制關閉GUI線程中的線程的好方法。 –

+0

@ØyvindKnobloch-Bråthen - 請告訴我什麼是從GUI線程強制殺死Backgroundworker線程的壞方法。 (DoWork中沒有循環) – Zeeshanef

3

設置e.Cancel什麼都不做,如果CancellationPending爲true,您需要使用return或其他任何方法(在您停止所做的事情之後)基本上脫離DoWork()。

喜歡的東西:

private void DoWork(...) 
{ 
    // An infinite loop of work! 
    while (true) 
    { 
     // If set to cancel, break the loop 
     if (worker.CancellationPending) 
      break; 

     // Sleep for a bit (do work) 
     Thread.Sleep(100); 
    } 
} 

的DoWork()在一個單獨的線程UI線程來執行,你可以使用BackgroundWorkr.ReportProgress報告給UI線程()。

0

繼續檢查邏輯的else部分中的CancellationPending = True標誌,並在返回true時返回。

2

一旦DoWork事件被觸發並且我的程序控件位於Business層中定義的函數中,如何返回到DoWork事件以設置'e.Cancel = true'?

你不知道。如果您希望在執行業務層期間取消,那麼您的業務層必須支持取消。因此,您有兩種選擇:

  1. 在您的DoWork方法中,只調用短時業務層方法並檢查兩者之間的CancellationPending。
  2. 使您的業務圖層方法取消感知,即將BackgroundWorker傳遞給它們,並讓它們定期檢查CancellationPending(並且在它變爲true時重新調用)。
0

代碼e.Cancel = true只在BackgroundWorker上設置一個狀態,以便它知道它已被取消,它實際上並不取消該過程。

您必須在您的方法循環中檢查CancellationPending,並檢查break it或return

void DoWork(object sender, DoWorkEventArgs e) { 
    for (int i = 0; i < length; i++) { 
     if(e.CancellationPending) { 
      return; 
     } 
     // Long running code 
    } 
}