抛出并捕获exception后继续执行代码

抛出exception后如何恢复代码执行?

例如,请使用以下代码:

namespace ConsoleApplication1 { public class Test { public void s() { throw new NotSupportedException(); string @class = "" ; Console.WriteLine(@class); Console.ReadLine(); } } public class Program { public static void Main(string[] args) { try { new Test().s(); } catch (ArgumentException x) { } catch (Exception ex) { } } } } 

在单步执行时捕获exception后,程序将停止运行。 我怎么还能继续执行?

编辑:我特别指的是Console.WriteLine(@class)行; 似乎没有被击中,因为当我在调试模式下运行它时,程序退出调试模式。 我想跑到这条线并停下来。

谢谢

好吧,在catch块之后你没有任何代码,所以程序会停止运行。 不确定你要做什么。

以下内容应certificate程序不会在catch块之后简单地“停止”。 如果有要执行的代码,它将在catch块之后执行代码:

 static void Main(string[] args) { try { new Test().s(); } catch (ArgumentException x) { Console.WriteLine("ArgumentException caught!"); } catch (Exception ex) { Console.WriteLine("Exception caught!"); } Console.WriteLine("I am some code that's running after the exception!"); } 

代码将根据捕获的exception打印相应的字符串。 然后,它将打印I am some code that's running after the exception! 在末尾。

UPDATE

在你的编辑中你问为什么Console.WriteLine(@class); 似乎没有被击中。 原因是您在s()方法的第一行显式抛出exception; 任何后续内容都会被忽略。 遇到exception时,执行停止,exception在调用堆栈中向上传播,直到相应的处理程序可以处理它(这可能是一个catch块,对应于在同一方法中包装有问题的语句的try ,或者它可能如果没有找到合适的处理程序,程序将以堆栈跟踪终止[至少在Java中 – 不确定C#中是否发生相同的情况]。

如果您想要访问Console.WriteLine行,那么您不应该在方法的开头显式抛出exception。

如果您担心方法中会抛出exception但您希望该方法继续,请在方法内添加一个error handling程序。

 class Test { public void s() { try { // Code that may throw an exception throw new NotSupportedException(); } catch(Exception ex) { // Handle the exception - log?, reset some values? } string @class = "" ; Console.WriteLine(@class); Console.ReadLine(); } } 

您还可以返回bool或其他值来指示状态。

听起来你想要可恢复的例外。 C#没有做可恢复的exception,我怀疑CLR是否支持它们。

抛出exception的目的是在调用环境中的某些东西(参数,对象状态,全局状态)使函数的操作无法或无效时,中止函数和整个操作(调用堆栈)。 例如,将零参数传递给需要通过该参数划分数量的函数。 除以零不会产生有意义的结果,如果这是函数的唯一目的,那么函数也不能返回有意义的结果。 所以,抛出exception。 这将导致执行跳转到最近的catch或最终阻塞调用堆栈。 没有返回抛出exception的函数。

如果要在调试器中单步执行代码以跟踪Console.WriteLine()调用,则需要从代码中删除抛出新的NotSupportedException()行并重新编译。

免责声明:我并不是说你实际上是这样做的。

您可以使用以下代码模仿旧的VB样式On Error Resume Next。

 public static class ControlFlow { public static Exception ResumeOnError(Action action) { try { action(); return null; } catch (Exception caught) { return caught; } } } 

然后它可以像下面这样使用。

 public static void Main() { ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); }); ControlFlow.ResumeOnError(() => { Console.WriteLine(); }); ControlFlow.ResumeOnError(() => { Console.ReadLine(); }); } 

我把一些简单的代码放在一起来捕获catch块中抛出的exception:

 try { //do code here } catch (Exception ex) { try { SomeMethod1(); } catch { } try { SomeMethod2(); } catch { } try { SomeMethod3(); } catch { } } finally { //cleanup goes here } 

执行仍然很重要,但在捕获到exception后没有代码。 如果你想重复调用s,那么考虑在while循环中包装try / catch块。

程序停止运行,因为没有以下代码在Main()方法中执行! 您可以在代码中添加以下行,以使程序保持运行,直到有控制台输入:

 Console.ReadLine(); 

对于该代码,您不能。 如果将任务分解为较小的块,则可以在下一个块中恢复。 但通常情况下,使用与exception不同的机制报告非致命错误更容易,例如返回是否继续的回调函数。

您可以在调试中使用“步进”function来实现每次运行。

 public static void Main() { for (int j = 0; j <= 100000; j++) { try { // TODO: Application logic... } catch { System.Threading.Thread.Sleep(1000); } } }