[英]Try/Catch exception continue from line that caused the exception
抛出异常时,如何捕获它然后从导致错误的行开始继续执行?
编辑:我们的程序与Indesign服务器通信,它一直崩溃并抛出随机的COM相关错误(这些错误与服务器本身的错误有关)。 Indesign Server也需要很长时间来处理命令,因此当它崩溃时,我们希望避免重新启动执行。 相反,我们希望从导致异常的行继续。 程序中的任何行都可能导致异常。 所以从技术上讲,我们不能使用循环。
抛出异常时,如何捕获它然后从导致错误的行开始继续执行? (不是下一行;重试导致异常的行。)
不要试图这样做。 你正在从错误的方向接近这个问题。
问题是你有一个不可靠的子系统。 您有一个处理该不可靠子系统的所需策略,即重试该操作直到成功为止。 如果是这种情况,那么不要将该逻辑放在使用子系统的业务线代码中 。 业务线代码应该是关于业务逻辑的,而不是关于您选择处理片状子系统的机制。 将机制隔离到特定类,使不可靠的子系统成为可靠的子系统。
也就是说,构建一个与不可靠子系统具有相同接口的代理类 ,并将重试逻辑隔离到该代理类中。 然后,业务线代码可以使用代理类作为可靠的子系统。
也就是说,“重试它直到它运作”的政策可能是一个糟糕的政策。 如果子系统真正被打破并且不仅仅是以某种短暂的方式存在片状,那么“重试直到它工作”意味着“永远等待”,并且大多数用户不喜欢永远等待。 例如,如果异常是路由器被拔出而不是某些瞬态条件的结果,则坐在循环中直到有人将路由器插回来似乎是个坏主意。
您必须包围任何可能在其自己的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);
请记住,应谨慎使用这两种方法。 前者会使你的代码混乱很多,而后者可能会花费比你想象的更多的时间(因为如果出现意外情况,通常会更好地提醒用户。因此强调一个瞬态异常,你如果你再试一次,真的会期望会消失。)
如果你正在寻找一些通用的东西,那么使用lambda就可以了。 例如
public static class Exception {
public static void Continue(Action action) {
try {
action();
} catch {
// Log
}
}
}
Exception.Continue(() => Statement1());
Exception.Continue(() => Statement2());
尽管大规模使用,我不认为这是一个理想的解决方案。 它会为您使用此语句的每个语句导致额外的委托分配,委托调用和方法调用。 相反,我会专注于识别导致问题的函数,并为它们单独添加显式包装器。
你可以这样做:
//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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.