c#在循环中抛出新的异常吗?

时间:2012-07-24 01:46:14

标签: c#-4.0

我有一个通过外部Web服务检索的记录列表。一些数据是垃圾,并希望通过抛出新的异常来记录失败的记录。

想知道这是否是最佳处理方式,因为我读取异常会影响性能?

Pseudo code e.g. 

try
Loop through listOfRecords
  perform logic.
catch
  throw new exception (record details)

2 个答案:

答案 0 :(得分:1)

这取决于遇到异常时您想要对其余记录执行的操作。您当前的实现将在第一个错误时终止循环。

但是,如果您只是想以某种方式将记录标记为“未处理”或“错误”并继续其余记录,则您需要完全在循环内处理错误:

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;
}

如果要向异常添加上下文,可以在再次抛出它之前修改其属性。或者甚至更好,抛出自定义异常(不是Exception)并将现有的异常附加为InnerException属性:

try
{
    // something
}
catch (Exception ex)
{
    throw new RecordProcessingException("some additional context", ex);
}

另一方面,如果在当前上下文中对异常没有任何意义,甚至根本不抓它。让它冒泡堆栈,直到它遇到可以有意义地处理它的代码。

答案 1 :(得分:0)

这不是最好的方法,因为您只需要日志写入功能。只需写入日志并continue循环。