我正在编写一个可以通过多个步骤提供任务的应用。我有一些类似于下面的代码,我想知道这是否是处理异常的常规方法。这个代码可能永远不会被其他人看到,但它可能是,所以我想知道我正在按照任何人的预期处理异常。
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接口,因此Execute的实现不是我自己的(在这个例子中,有人可以实现接口)。我的代码只是加载库并运行任何ITasks及其ITaskSteps。
答案 0 :(得分:7)
继续并捕获异常以记录它们的存在。但是如果你还没有真正解决导致抛出异常的问题,那么请重新抛出它以便调用者处理。不要吞下它。
上面的代码捕获TaskIsBogusException
和PrinterOnFireException
并以相同的方式处理它们:记录它并继续执行下一个任务。使用虚假任务执行此操作很好,因为无论如何你已经完成了任务,但是如果你抓到PrinterOnFireException
并且不重新抛出它,那么通过高兴,打印机最好还是不会着火。 / p>
如果您不打算重新抛出,那么只捕获您的代码知道如何处理的特定异常类型。让其他一切(你不知道如何处理的东西,或你从未想过的东西)传播到下一个可用的异常处理程序。
答案 1 :(得分:2)
如果{for循环中发生step.Execute()
是唯一发生的事情,则以下情况可能更好:(为澄清而编辑)
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
}
}
这样您就不会重新抛出异常。
答案 2 :(得分: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
}
答案 3 :(得分:0)
当我有一个我想要完成的任务列表时,即使其中一些任务失败,我也做了类似的事情。实际上有些时候我知道很有可能会失败,但我不想在所有步骤完成之前突破循环。
我认为这很有道理。
答案 4 :(得分:0)
我想我可能会这样写,但你的方法也可以。
foreach(var step in task.Steps)
{
try
{
step.Execute();
}
catch(Exception ex)
{
LogStepError(step, ex);
LogTaskFailure(task);
break;
}
}
答案 5 :(得分:0)
您可能希望使用return变量处理任务的完成,并在整个代码片段上使用Exception来捕获任何一般异常。
示例:
try{
foreach(var step in task.Steps)
{
if(!step.Execute()){
break;
}
}
}catch(Exception ex)
{
}