【发布时间】:2012-12-20 15:47:50
【问题描述】:
下面的代码显示了尝试封装逻辑以在捕获异常时重新运行某些东西。
是否存在模式或其他东西可以做到这一点?或者您会建议对该代码进行哪些改进?
public static void DoWhileFailing(int triesAmount, int pauseAmongTries, Action codeToTryRun) {
bool passed = false;
Exception lastException = null;
for (int i = 0; !passed && i < triesAmount; i++) {
try {
if (i > 0) {
Thread.Sleep(pauseAmongTries);
}
codeToTryRun();
passed = true;
} catch(Exception e) {
lastException = e;
}
}
if (!passed && lastException != null) {
throw new Exception(String.Format("Something failed more than {0} times. That is the last exception catched.", triesAmount), lastException);
}
}
【问题讨论】:
-
如果你有
passed = true,你可以只使用return,最后你不需要检查它,只需抛出一个异常。有些人真的讨厌多个出口点,有些人则不然。在这里,我认为多个退出点是有意义的。 -
The "catch(Exception e)" is wronge 你应该抓住你期望能够从中恢复的期望并检查它的细节。例如。数据库异常检查它是否由于死锁而失败。否则这段代码很像我们除了在遇到异常时清除连接缓存之外的代码,因为 SqlConnection 将重用断开的连接。
-
重试你的意思是什么?
-
@IanRingrose,也许只是有一个通用参数来指定在重新运行之前要捕获哪个异常,可能会更好。类似于 juharr 的回答,尽管他建议将异常“传递”给调用者,调用者可以通过委托检查异常。
-
@Luciano,我发现的问题是数据库死锁和集群故障转移会抛出与“真实”数据库错误相同的异常类。因此需要处理异常消息文本和/或错误号。
标签: c# exception-handling for-loop try-catch