Try/Catch异常从引起异常的行继续
本文关键字:异常 继续 Catch Try | 更新日期: 2023-09-27 18:06:03
当抛出异常时,我如何捕获它,然后从引起错误的行开始继续执行?
编辑:我们的程序与Indesign服务器通信,Indesign服务器一直崩溃并抛出随机的COM相关错误(这些错误与服务器本身的错误有关)。Indesign Server也需要很长时间来处理命令,所以当它崩溃时,我们希望避免重新启动执行。相反,我们希望从引起异常的行继续执行。程序中的任何一行都可能导致异常。所以严格来说,我们不能使用循环
当抛出异常时,如何捕获它,然后从引起错误的行开始继续执行?(不是下一行;重试引起异常的行
不要尝试那样做。你解决这个问题的方向错了。
问题是你有一个不可靠的子系统。您有一个处理不可靠子系统的策略,即重试操作直到操作成功。如果是这种情况,那么不要将逻辑放在使用子系统的业务代码中。业务线代码应该与业务逻辑有关,而不是与您选择的处理脆弱子系统的机制有关。将机制隔离到一个特定的类,使不可靠的子系统变成可靠的子系统。
也就是说,构建一个与不可靠子系统具有相同接口的代理类,并将重试逻辑隔离到该代理类中。然后,业务线代码可以使用代理类作为可靠的子系统。也就是说,"重试直到成功"的策略可能是一个糟糕的策略。如果子系统真的坏了,而不是以某种暂时的方式破碎,那么"重试直到它工作"意味着"永远等待",而大多数用户不喜欢永远等待。例如,如果异常是由于路由器被拔掉了,而不是由于某种暂时的情况,那么坐在那里直到有人把路由器重新插上,这似乎是一个坏主意。
如果您正在寻找通用的东西,那么使用lambda就可以了。例如
public static class Exception {
public static void Continue(Action action) {
try {
action();
} catch {
// Log
}
}
}
Exception.Continue(() => Statement1());
Exception.Continue(() => Statement2());
我不认为这是一个理想的解决方案,但大规模使用。它会为您使用此方法的每个语句导致额外的委托分配、委托调用和方法调用。相反,我会专注于识别导致问题的函数,并为它们单独添加显式包装。
要做到这一点,您必须将任何可能在其自己的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);
记住这两种方法都应该谨慎使用。前者会使您的代码相当混乱,而后者可能会花费比您想象的更多的时间(因为如果发生意外情况,通常只是提醒用户是一个更好的主意)。因此,如果您再次尝试,那么您真正期望的对瞬态异常的强调将会消失。
你可以这样做:
//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;
}
}
最好的解决方案是将每行放在单独的try/catch
中。的例子:
try { function1(); } catch { }
try { function2(); } catch { }
try { function3(); } catch { }
您也可以将它们分组在一个块中
try
{
SomeCodeHere();
try { function1(); } catch { }
try { function2(); } catch { }
try { function3(); } catch { }
}
catch
{
}
我不知道c#,但这是一个javascript,可以使脚本运行多次,如果有一个错误。
try {
for (var i=0; (i < t && condition) || i === 0; i++) {
//t is how many times you want the code to run.
//condition should be true when there is an error.
//The code you want to execute multiple times if it fails.
}
} catch (e) {
//The code you want to execute if the code still runs into an error after being repeated multiple times.
}
例如,下面的代码模拟了将变量设置为来自另一个服务器的响应的情况。并且,服务器在脚本第六次运行时响应。
try {
for (var i = 0; (i < 10 && typeof response === "undefined") || i === 0; i++) {
var response = (i === 5) ? 1 : undefined;
if (typeof response === "undefined") {console.log("ERROR!! #" + i)} else {console.log("Success!! #" + i)};
if (i === 9 && typeof response === "undefined") {throw new Error("Fail to get response from other server")};
}
} catch (e) {
console.log("Error Message: '" + e + "'");
}
您可以运行上面的代码来查看效果。以下是另一个服务器不响应的情况。
try {
for (var i = 0; (i < 10 && typeof response === "undefined") || i === 0; i++) {
var response = (i === -1) ? 1 : undefined;
if (typeof response === "undefined") {console.log("ERROR!! #" + i)} else {console.log("Success!! #" + i)};
if (i === 9 && typeof response === "undefined") {throw new Error("Fail to get response from other server")};
}
} catch (e) {
console.log("Error Message: '" + e + "'");
}
你也可以把它变成一个函数来方便地使用。
function retry(code,times,condition,errorMessage) {
try {
for (var i = 0; (i < times && eval(condition)) || i === 0; i++) {
eval(code);
if (i === times-1 && eval(condition) && typeof errorMessage !== "undefined") {throw new Error(errorMessage)};
}
} catch (e) {
console.log("Error Message: '" + e + "'");
}
}
使用函数的前两个示例。
function retry(code,times,condition,errorMessage) {
try {
for (var i = 0; (i < times && eval(condition)) || i === 0; i++) {
eval(code);
if (eval(condition)) {console.log("ERROR!! #" + i)} else {console.log("Success!! #" + i)};
if (i === times-1 && eval(condition) && typeof errorMessage !== "undefined") {throw new Error(errorMessage)};
}
} catch (e) {
console.log("Error Message: '" + e + "'");
}
}
retry("var response = (i === 5) ? 1 : undefined;",10,"typeof response === 'undefined'","Fail to get response from other server")
retry("var response = (i === -1) ? 1 : undefined;",10,"typeof response === 'undefined'","Fail to get response from other server")
我希望这能帮助到一些人