当抛出异常时,如何捕获它然后从导致错误的行开始继续执行?
编辑: 我们的程序与Indesign Server进行通信,Indesign Server一直崩溃并抛出随机的COM相关错误(这些错误与服务器本身的错误有关)。 Indesign Server也需要很长时间来处理命令,因此当它崩溃时,我们希望避免重新启动执行。相反,我们希望从导致异常的行继续。程序中的任何行都可能导致异常。从技术上讲,我们不能使用循环。
答案 0 :(得分:12)
当抛出异常时,如何捕获它然后从导致错误的行开始继续执行? (不是下一行;重试导致异常的行。)
不要试图这样做。你正在从错误的方向接近这个问题。
问题是你有一个不可靠的子系统。您有一个处理该不可靠子系统的所需策略,即重试该操作直到成功为止。如果是这种情况,则不要将该逻辑放在使用子系统的业务线代码中。业务线代码应该是关于业务逻辑的,而不是关于您选择处理片状子系统的机制。 将机制隔离到特定类,使不可靠的子系统成为可靠的子系统。
即,构建一个与不可靠子系统具有相同接口的代理类,并将重试逻辑隔离到该代理类中。然后,业务线代码可以使用代理类作为可靠的子系统。
也就是说,“重审它直到它运作”的政策可能是一个糟糕的政策。如果子系统真正被打破并且不仅仅是以某种短暂的方式存在片状,那么“重试直到它工作”意味着“永远等待”,并且大多数用户不喜欢永远等待。例如,如果异常是由于路由器被拔掉而不是某些瞬态情况,那么就坐在循环中直到有人将路由器插回来似乎是一个坏主意。
答案 1 :(得分:3)
您必须将任何可能在其try
/ catch
块中引发异常的行包围起来。
所以而不是
try
{
StatementOne(); // Exception thrown here
StatementTwo();
}
catch (SOneException) { ... }
你必须这样做:
try
{
StatementOne();
}
catch (SOneException) { ... }
StatementTwo();
如果由于(希望是瞬态)异常而需要重试某个操作,可以使用如下方法:
public static class ExceptionHelper
{
public static void TryNTimesAndThenThrow(Action statement, int retryCount)
{
bool keepTrying = false;
do
{
try
{
statement();
keepTrying = false;
}
catch (Exception)
{
if (retryCount > 0)
{
keepTrying = true;
retryCount--;
}
else
{
// If it doesn't work here, assume it's broken and rethrow
throw;
}
}
} while (keepTrying)
}
}
然后你可以写:
ExceptionHelper.TryNTimesAndThenThrow(() => MightThrowATransientException(), 3);
请记住,应谨慎使用这两种方法。前者会使你的代码混乱很多,而后者可能会花费比你想象的更多的时间(因为如果出现意外情况,通常会更好地提醒用户。因此强调一个瞬态异常,你如果你再试一次,真的会期望会消失。)
答案 2 :(得分:3)
如果你正在寻找一些通用的东西,那么使用lambda就可以了。例如
public static class Exception {
public static void Continue(Action action) {
try {
action();
} catch {
// Log
}
}
}
Exception.Continue(() => Statement1());
Exception.Continue(() => Statement2());
我不认为这是大规模使用的理想解决方案。它会为您使用此语句的每个语句导致额外的委托分配,委托调用和方法调用。相反,我会专注于识别导致问题的函数,并为它们单独添加显式包装。
答案 3 :(得分:0)
你可以这样做:
//Retry logic on opening the connection
int retries = 0;
openconnection:
try
{
connection.Open();
}
catch
{
retries++;
//Wait 2 seconds
System.Threading.Thread.Sleep(2000);
if (retries < MAXRETRIES)
{
goto openconnection;
}
else
{
throw;
}
}