异常后继续运行
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 我也没有使用异步任务——只有通用的Action
s(适合提供的方法签名)。 功能上效果相同 - 问题的要点似乎是“我如何处理异常但不中断执行流程”,这两种方法都可以解决。
@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)
【讨论】:
以上是关于异常后继续运行的主要内容,如果未能解决你的问题,请参考以下文章