2009-07-23 67 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 
}