2009-07-23 96 views
3

我正在編寫一個應用程序,可以通過多個步驟提供任務。我有一些類似於下面的代碼,我想知道這是否是處理異常的正常方法。這個代碼可能永遠不會被其他人看到,但它可能是,所以我想知道我正在處理任何人都會遇到的異常。何時處理異常?

IEnumerable<Task> Tasks; 

foreach(var task in Tasks) 
{ 
try 
{ 
    //boiler plate prep for task (loading libraries, connecting, logging start, etc) 

    foreach(var step in task.Steps) 
    { 
     try 
     { 
     step.Execute(); 
     } 
     catch(Exception ex) 
     { 
     LogStepError(step, ex); 
     throw; 
     } 
    } 

    //Notify parties task has been completed successfully, log task completion 
    } 
    catch(Exception ex) 
    { 
     LogTaskFailure(task); 
    } 
    finally 
    { 
    //close connections, etc 
    } 
} 



interface ITaskStep 
{ 
    void Execute() 
    { 

    }    
} 

我也想補充的是,任務步驟正在實施ITaskStep接口,所以執行的執行是不是我自己的(當然這是在這種情況下,但有人可以實現的接口)。我的代碼只是加載庫並運行任何ITasks和ITaskSteps。

回答

7

來吧,捕獲異常記錄他們的存在。但是如果你沒有真正解決導致異常拋出的問題,那麼請重新拋出它以供調用者處理。不要吞下去。

您上面的代碼捕獲了TaskIsBogusExceptionPrinterOnFireException,並以相同的方式對待它們:記錄它並繼續執行下一個任務。做一個虛假的任務是沒問題的,因爲你已經完成了任務,但是如果你抓住了一個PrinterOnFireException並且不重新拋出它,那麼通過golly,打印機最好不要着火。

如果你不打算重新拋出,那麼只捕獲你的代碼知道如何處理的特定異常類型。讓所有其他東西(無論你不知道如何處理的東西,或者你從未想過的東西)傳播到下一個可用的異常處理程序。

0

當我有我想要完成的任務列表時,我做了類似的次數,即使其中一些失敗了。事實上,有些時候我知道有一個很可能會失敗的機會,但是我不想在所有步驟完成之前跳出循環。

我認爲這很有意義。

2

如果step.Execute()是這是發生在你的for循環,下面可能會更好唯一:(響應澄清編輯)

IEnumerable<Task> Tasks; 

foreach(var task in Tasks) 
{ 
    try 
    { 
    //boiler plate prep for task 
    } 
    catch(Exception ex) 
    { 
    LogTaskFailure(task); 
    continue; 
    } 
    foreach(var step in task.Steps) 
    { 
     try 
     { 
     step.Execute(); 
     } 
     catch(Exception ex) 
     { 
     LogStepError(step, ex); 
     LogTaskFailure(task); 
     break; 
     } 
    } 
} 

class TaskStep 
{ 
    private void Execute() 
    { 
     //do some stuff, don't catch any exceptions 
    }    
} 

這樣你就不會重新拋出異常。

+0

鍋爐準備是一些其他的東西發生在我想包裝在try/catch循環之外。它正在拉取一些庫依賴關係,並將它們寫入磁盤供將來使用以及連接到遠程系統等。 – scottm 2009-07-23 16:56:17

+0

使用此代碼,如果鍋爐板代碼引發異常,則不會執行更多任務,這不是我想要的。 – scottm 2009-07-23 17:00:48

0

我想我可能會這樣寫,但你的方法也可以。

foreach(var step in task.Steps) 
     { 
      try 
      { 
      step.Execute(); 
      } 
      catch(Exception ex) 
      { 
      LogStepError(step, ex); 
      LogTaskFailure(task); 
      break; 
      } 
     } 
0

你可能想處理使用返回varibale和使用異常對整個代碼pience捕捉任何通用的異常你的任務的完成。

例子:

try{ 
foreach(var step in task.Steps) 
     { 
      if(!step.Execute()){ 
       break; 
      } 

     } 
}catch(Exception ex) 
{ 
} 
2

您正趕上了所有的異常是確定,正如你所說的是最常用的方法,但我不認爲這是正確的。

我認爲你應該抓住特定的例外。如果你這樣做,你可以分開他們,你會發現有一些例外,你根本無法處理,但也有其他人可以。由於您完全知道您的代碼正在發生什麼,因此代碼會更好,更強大。

這是一個例子:



try 
{ 
    //Your stuff 
} 
catch(DivideByZeroException ex) 
{ 
    //Could you manage this? 
} 
catch(NullReferenceException ex) 
{ 
    //Could you manage this one? 
} 
catch(IOException ex) 
{ 
     //What about this one? 
} 
finally 
{ 
     //Any cleanup code 
}