抛出异常后如何恢复代码执行?
例如,请使用以下代码:
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)
{
}
}
}
}
在单步执行时捕获异常后,程序将停止运行。我怎么还能继续执行?
编辑:我特别指的是Console.WriteLine(@class);似乎没有被击中,因为当我在调试模式下运行它时,程序退出调试模式。我想跑到这条线上并停下来。
由于
答案 0 :(得分:32)
好吧,catch
块之后没有任何代码,所以程序会停止运行。不确定你要做什么。
以下内容应证明该程序不会在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!");
}
代码将根据捕获的异常打印相应的字符串。然后,它会在最后打印I am some code that's running after the exception!
。
<强>更新强>
在您的编辑中,您问为什么Console.WriteLine(@class);
似乎没有被点击。原因是您明确地在s()
方法的第一行中抛出异常;任何后续内容都会被忽略。遇到异常时,执行停止,异常在调用堆栈中向上传播,直到相应的处理程序可以处理它(这可能是catch
块,对应于包含有问题语句的try
在同一个方法中,或者它可能是调用堆栈中的catch
块。如果找不到合适的处理程序,程序将以堆栈跟踪终止[至少在Java中 - 不确定是否发生相同的情况C#])。
如果你想点击Console.WriteLine
行,那么你不应该在方法的开头显式抛出异常。
答案 1 :(得分:8)
听起来你想要可恢复的例外。 C#没有做可恢复的异常,我怀疑CLR是否支持它们。
抛出异常的目的是在调用环境中的某些内容(参数,对象状态,全局状态)使函数的操作无法或无效时,中止函数和整个操作(调用堆栈)。例如,将零参数传递给需要通过该参数划分数量的函数。除以零将不会产生有意义的结果,如果这是函数的唯一目的,那么函数也不能返回有意义的结果。所以,抛出异常。这将导致执行跳转到最近的catch或最终阻塞调用堆栈。没有返回抛出异常的函数。
如果要在调试器中单步执行代码以跟踪Console.WriteLine()调用,则需要从代码中删除抛出新的NotSupportedException()行并重新编译。
答案 2 :(得分:7)
如果您担心方法中会抛出异常但希望方法继续,请在方法中添加错误处理程序。
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或其他值来表示状态。
答案 3 :(得分:3)
免责声明:我并不是说你实际上是这样做的。
您可以使用以下代码模仿旧的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(); });
}
答案 4 :(得分:1)
我将一些简单的代码放在一起以捕获在catch块中抛出的异常:
try
{
//do code here
}
catch (Exception ex)
{
try { SomeMethod1(); }
catch { }
try { SomeMethod2(); }
catch { }
try { SomeMethod3(); }
catch { }
}
finally
{
//cleanup goes here
}
答案 5 :(得分:0)
执行仍在继续,但在捕获异常后没有代码。如果你想重复调用s,那么考虑在while循环中包装try / catch块。
答案 6 :(得分:0)
程序停止运行,因为在Main()方法中没有以下代码要执行!您可以在代码中添加以下行,以使程序保持运行,直到有控制台输入:
Console.ReadLine();
答案 7 :(得分:0)
对于该代码,您不能。如果将任务分解为较小的块,则可以在下一个块中恢复。但通常情况下,使用与异常不同的机制报告非致命错误更容易,例如返回是否继续的回调函数。
答案 8 :(得分:0)
您可以在调试中使用“步进”功能来实现每次运行。
答案 9 :(得分:-5)
public static void Main()
{
for (int j = 0; j <= 100000; j++)
{
try
{
// TODO: Application logic...
}
catch
{
System.Threading.Thread.Sleep(1000);
}
}
}