我有一个通过外部 Web 服务检索到的记录列表。一些数据是垃圾,并且想通过抛出一个新的异常来记录失败的记录。
想知道这是否是最好的处理方式,因为我读取异常会影响性能?
Pseudo code e.g.
try
Loop through listOfRecords
perform logic.
catch
throw new exception (record details)
我有一个通过外部 Web 服务检索到的记录列表。一些数据是垃圾,并且想通过抛出一个新的异常来记录失败的记录。
想知道这是否是最好的处理方式,因为我读取异常会影响性能?
Pseudo code e.g.
try
Loop through listOfRecords
perform logic.
catch
throw new exception (record details)
这取决于遇到异常时您想对其余记录做什么。您当前的实现将在第一个错误时终止循环。
但是,如果您只是想以某种方式将记录标记为“未处理”或“错误”并继续处理剩余记录,则您希望完全在循环中处理错误:
foreach (var record in records)
{
try
{
Process(record);
}
catch (TypedException ex)
{
LogError(ex);
MarkAsUnprocessed(record, ex);
// respond in some other way as well?
}
}
最终,异常处理逻辑属于在逻辑上对处理异常有意义的任何地方。 捕获异常是容易的部分,这是所使用语言的简单构造。有意义地处理异常完全是另一回事,它是一个独立于所使用语言的逻辑结构。
编辑:同样值得注意的是,您的伪代码暗示了这种处理异常的方式:
try
{
// something
}
catch
{
throw new Exception("something");
}
这是非常糟糕的做法。抛出一个全新的异常本质上是丢弃捕获的异常,从而消除了一些非常有用的调试信息(其中最重要的是堆栈跟踪)。如果您想立即记录异常,然后让它继续向上堆栈,只需单独使用关键字throw
:
try
{
// something
}
catch (Exception ex)
{
// log the exception
throw;
}
如果你想为异常添加上下文,你可以在再次抛出它之前修改它的属性。或者甚至更好,抛出一个自定义异常(not Exception
)并将现有异常附加为InnerException
属性:
try
{
// something
}
catch (Exception ex)
{
throw new RecordProcessingException("some additional context", ex);
}
另一方面,如果在当前上下文中对异常没有任何意义,甚至根本不要捕获它。让它在堆栈中冒泡,直到遇到可以有意义地处理它的代码。
这不是最好的方法,因为您只需要日志写入功能。只需写入日志和continue
循环。