2013-10-11 82 views
1

我正在使用BackgroundWorker來處理長時間運行的外部操作。但是用戶可以選擇取消後臺操作。由於我的自定義BackgroundWorker支持Thread.Abort(),因此當用戶從主線程觸發Cancel時,我所做的全部爲BackgroundWorker.Abort()線程終止建議需要

但是線程並未實際終止,它仍在完成外部進程。有什麼方法可以立即終止線程嗎?

我沒有在外部處理控制,所以不能發送任何標誌的做法一樣while (checkThreadCancelled){}

下面是我的僞代碼。

任何幫助?

AbortableBackgroundWorker _bgWorker; 

void MainThreadFunc() 
{ 
    _bgWorker = new AbortableBackgroundWorker(); 
    _bgWorker.DoWork += new DoWorkEventHandler(bg_DoWork); 
    _bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler 
        (bg_RunWorkerCompleted); 
    _bgWorker.WorkerSupportsCancellation = true; 
    _bgWorker.RunWorkerAsync(); 
} 

void bg_DoWork() 
{ 
    //Call external dll function for processing 
} 

void bg_RunWorkerCompleted() 
{ 

    //Process completed code 
} 

void CancelBgProcess() 
{ 
    if(_bgWorker != null) 
     _bgWorker.Abort(); 
} 

回答

3

Abort方法依賴於工作線程與它合作。最終它會導致CLR拋出一個異常,指示線程將中止,線程可以隨意處理。

當你的工作線程在執行DLL東西時,CLR是不是在控制,因此它並沒有引發異常的選項。

你必須使用Win32 API TerminateThread,但這樣做的選擇是嚴重的,可能會或可能不會導致你的過程中的腐敗。 TerminateThread並不是您應該選擇的選項。

既然你不能修改您所呼叫的圖書館,你有兩種選擇。第一種也是最簡單的方法,降低後臺線程的優先級並忽略取消後繼續運行的事實。

二是要在一個獨立的過程,而不是線程啓動你的後臺操作。在此時,如果取消操作,您可以終止整個過程。如果你走這條路線,你需要選擇某種形式的IPC來傳遞庫的輸入和輸出參數。

TasksCancellationTokens最終不會在這種情況下幫助你,因爲你最終會在同一個地方:執行庫代碼,將不會與你合作以取消。

0

試試這個:

if (_bgWorker.IsBusy) 
      { 
       _bgWorker.WorkerSupportsCancellation = true; 
       //To cancel the Thread if Closing the Application 
       //while the Background Thread Worker is Still running on Background. 
       _bgWorker.CancelAsync();     
      } 

它將停止當前線程處理,並會取消該線程上正在進行的操作。 可能會對你有所幫助