2009-06-26 26 views
-1

我有一個可以取消的後臺工作。Backgroundworker:取消期間的例外

當CancelPending變量變爲true(響應UI上的用戶交互時,正在調用worker.CancelAsynch()),正常流程會自行中斷,因爲如果這樣(因爲正常流程被中斷,大量空引用異常被拋出)

因此,當工作人員返回時,我希望能夠區分當工作人員未被取消時引發的異常(當工人 被取消時(默默地忽略它們) UI)。

我的代碼如下(爲C#/ VB混合對不起......):

工人類:

Public Class ClassBaseGetObjectsWorker 
    Inherits System.ComponentModel.BackgroundWorker 


Protected Overrides Sub OnDoWork(ByVal e As System.ComponentModel.DoWorkEventArgs) 
     Try 

      Dim cpt As Int16 = 0 
      While cpt < 5 
       System.Threading.Thread.Sleep(1000) 
       cpt = cpt + 1 
       If CheckForCancellation() Then 
        'Simulating exception due to cancel 
        Throw New Exception("Exception du to cancel !") 
       End If 
      End While 

     Catch exc As Exception 
      e.Cancel = Me.CancellationPending 
      Throw exc 
     End Try 

    End Sub 
End Class 

回叫:

void setObjSetCollWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
    if (e.Cancelled) { 
     resultLabel.Text += "Canceled"; 
     //e.Error is selently ignored 
    } 
    else { 
     if (e.Error != null) { 
      //Reporting errors arising during normal (uncanceled) flow 
      throw e.Error.InnerException; 
     } 
     else { 
      //Worker process finished without error or being canceled. 
      updateUIAfterBackgroundJob(); 
     } 
    } 
} 

然後,當我在做worker.CancelAsynch()時,e.Cancelled在Completed回調中設置爲false(這不是我所期望的)。如果我在工作人員註釋「Trow exc」,如果我再次測試 ,則e.Cancelled已正確設置爲true。

那麼,什麼是最簡潔的方式來獲取我想要的信息,那就是:我想知道當worker處於cancelPending狀態時,在完成的處理程序中彈出的異常是否被拋出。

(對不起,我的英文不好)

+0

工作代碼是什麼樣的,它如何處理被取消? – Thies 2009-06-26 11:28:17

+0

工作人員與上面的模擬代碼類似:它經歷幾個級別的函數調用,每個執行循環如果CancellationPending(通過委託檢查)變爲true,則退出。 考慮到流程中斷和結果將被丟棄的事實,那些循環和函數prematured退出導致異常是「正常」。 你爲什麼這麼問? – jfburdet 2009-06-26 11:49:54

回答

0

如果構建在OnDoWork代碼的最佳方式() - 實現拋出,當你發現消除了異常,請執行以下操作:

創建CancelException:

public class CancelException: Exception {} 

拋出此CancelException當檢測到取消未決:

if(CheckForCancellation()) throw new CancelException(); 

添加代碼周圍一個try-catch在你的OnDoWork() - 方法:

protected override void OnDoWork(DoWorkEventArgs e){ 
    try{ 
    //... 
    } 
    catch(CancelException){ 
    // silently return 
    return; 
    } 
} 

這樣,你的代碼將服從BackgroundWorker的合同(這是當你發現取消未決從OnDoWork()返回,而不是拋出異常),並且已取消的財產現在應該如您所期望的那樣