异常后继续运行

Posted

技术标签:

【中文标题】异常后继续运行【英文标题】:After an exception, keep on running 【发布时间】:2014-05-07 17:52:39 【问题描述】:

例如:

 try

   Task1();
   Task2();
   Task3();

catch (Exception ex)


现在如果 Task1() 发生异常,Task2 和 Task2 方法中的代码不会运行。程序停止。

我怎样才能让它在发生异常时,它下面的代码/方法会一直运行到最后。

谢谢

【问题讨论】:

如果您不希望它们以这种方式执行,那么将它们全部放在 try 块中是没有意义的。 做你想要达到的目标是不好的做法。在每个函数中创建可以让您的代码避免异常的检查。 我假设在您的 catch 块中您实际上正在做一些事情来处理异常,但只是没有费心实际发布它在这里的内容(这很好)。如果您实际上没有做任何事情,并且您的 catch 块确实是空白的,那么这几乎肯定是错误的。当您无法处理异常时,您不希望捕获异常。你永远不会知道你的程序什么时候不能正常工作,或者为什么它不能正常工作。 Guising OP 使用“Task”作为通用方法名称,并无意沿着 Task/async 路径前进。 【参考方案1】:

异常将执行移动到 try 块的末尾并进入 catch 块。要做你想做的事,你必须使用单独的 try/catch 块:

try

   Task1();

catch (Exception ex)



try

   Task2();

catch (Exception ex)



try

   Task3();

catch (Exception ex)


可以将您的任务放在一个集合中(前提是它们都具有相同的签名)并循环,但最终效果是相同的:

var tasks = new Action[] Task1, Task2, Task3;
foreach(var task in tasks)

    try
    
       task();
    
    catch (Exception ex)
    
    

【讨论】:

你的收藏想法似乎很有趣,你会怎么做? 猜测 OP 并不打算使用异步相关任务。你的答案的第一部分是正确的。不太确定第二部分是他们想要的。 @andleer 我也没有使用异步任务——只有通用的Actions(适合提供的方法签名)。 功能上效果相同 - 问题的要点似乎是“我如何处理异常但不中断执行流程”,这两种方法都可以解决。 @DStanley 完全同意,但认为您提出的解决方案超出了 OP 的几个数量级。仍然是一个正确的解决方案! @andleer 我认为你读的太多了——我所做的只是将三个函数调用包装到一个 Action 代表数组中——没有异步,没有线程,只是普通的旧同步 Action代表。由于 OP询问了关于收藏品的问题,我提供了一个示例。【参考方案2】:

目前,在您拥有的代码中,如果尝试 start Task1() 时抛出异常,则其他两个任务不会启动。如果该任务启动时没有错误,但导致任务处于Faulted 状态,那么您的其他任务已正确启动。

一般来说,在大多数情况下,人们不会期望像这样的方法会引发异常开始任务。空值检查参数是一种常见的做法,但除此之外,人们通常会期望此类方法不会启动任务。如果您对该方法有任何控制权,请考虑重新设计它,使其生成错误任务而不是引发异常,除非您有充分的理由不这样做。

您可能还想创建一个采用任务返回方法的方法,如果它无法生成任务,则改为创建错误任务。如果成功,它可以返回那个任务:

public static Task WrapExceptions(this Func<Task> function)

    try
    
        return function();
    
    catch (Exception e)
    
        var tcs = new TaskCompletionSource<bool>();
        tcs.SetException(e);
        return tcs.Task;
    

如果你想确保所有任务在启动任务时即使出现异常也能启动,那么你需要将每个方法调用包装在自己的try/catch中。

【讨论】:

是否有证据表明 OP 想要使用 Task 类?我认为他只是使用 Task1() 等作为他正在调用的其他方法的占位符名称。 @adv12 - 即使 OP 不想使用 Task 类,这仍然是良好设计的一个很好的例子。 +1,Servy。 @Brandon:在不知道这些方法调用的内容的情况下,用多线程代码替换三个顺序、同步的方法调用是个好设计吗?我认为不会。【参考方案3】:

将每个语句放在自己的 try-catch 块中:

try

   Task1();

catch (Exception ex)


try 
   Task2();

catch (Exception ex)


try 
   Task3();

catch (Exception ex)


【讨论】:

以上是关于异常后继续运行的主要内容,如果未能解决你的问题,请参考以下文章

java中如何抛出异常后继续运行

Java:抛出异常后如何终止执行后面的代码?

python怎么在异常处理后继续顺序执行?

第十二章 通过异常处理错误

java抛出异常后程序还会不会往下执行?

异常处理:显示异常信息,程序继续运行