C# 重试异常c情况下的StackTrace行为#
正如我现在已经说过的,为了保留原始的C# 重试异常c情况下的StackTrace行为#,c#,try-catch,stack-trace,throw,C#,Try Catch,Stack Trace,Throw,正如我现在已经说过的,为了保留原始的
,我们应该避免使用throw
捕获的异常,相反,我们应该只使用throw
子句
,它实际上是重新抛出
异常
问题是在几天前的一次采访中,我得到了一个代码来预测最终结果的stacktrace
:
class Program
{
static void Main(string[] args)
{
try
{
ReThrowException(); // line 17
}
catch (Exception x)
{
Console.WriteLine("Exception:");
Console.WriteLine(x.StackTrace); //line 22
}
}
private static void ReThrowException()
{
try
{
DivByZero();
}
catch
{
throw; //line 34
}
}
private static void DivByZero()
{
int x = 0;
int y = 1 / x; //line 41
}
}
异常发生在第41行
中,而在第34行,它只是通过保留原始的堆栈跟踪
来重新显示异常
我的回答是:
它应该指向异常实际所在的第41行
第一次发生,在中没有任何地方覆盖stackTrace
密码
但真正的答案如下:
Exception:
at TestConsole.Program.DivByZero() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 41
at TestConsole.Program.ReThrowException() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 34
at TestConsole.Program.Main(String[] args) in C:...\Projects\TestConsole\TestConsole\Program.cs:line 17
现在我想到两个问题:
1.为什么stackTrace
为17,34
行添加源?
2.在代码中,我应该怎么做才能将stackTrace指向第41行并删除其他源?“我应该怎么做才能将stackTrace指向第41行并删除其他源?”
别在34号线上接它
您应该只捕获您知道如何处理的异常。如果您曾经catch()
或catch(Exception)
那么您可能是错的(除非是为了记录日志而重新调用)
请记住,例外情况是“昂贵的”。你应该尽量避开它们。除零表示停止,如果代码的除数为零是“正常”的,那么这不是例外,应该用if
捕获
1.stackTrace为什么要为第17、34行添加源
不是其他源
,而是显示导致异常的跟踪的堆栈
跟踪。
正如名称StackTrace
所暗示的,它不是一个单点,同样也是一个路径
2.我应该在代码中做些什么,使stackTrace指向第41行并删除其他源
你不能,因为你的问题来自对stackTrace存在的误解。它没有向你显示“其他来源”。它是一个堆栈跟踪:它显示异常抛出点的调用堆栈。调用DivByZero
的地方可能很多,堆栈跟踪显示了确切调用它的方法,以及调用该方法的方法,等等,直到应用程序的入口点(或者线程处理程序,如果它在后台线程上,等等)。它说的是“Main在第17行调用了ReThrowException;ReThrowException在第34行调用了DivByZero(除了它遇到了‘throw’点,而不是原始的方法调用);DivByZero在第41行遇到了一个问题”。你是对的,但当它指向第34行时,似乎我使用了throw ex而不是throw子句。不。如果使用抛出ex代码>,则会丢失指向DivByZero
中第41行的堆栈跟踪部分<代码>抛出ex
将完全删除到目前为止记录的堆栈跟踪,然后重新开始是的,在本例中我丢失了原始文件,但它的行为就像我在第34行中抛出异常一样。不,不是--您读错了。查看第一个条目以查看引发异常的位置。其余条目显示异常“命中”的代码点,直到它最终被捕获并打印。堆栈跟踪不会显示引发异常的代码中的所有点:它会显示异常在代码中冒泡时通过的所有点。堆栈跟踪仍然会有一个ReThrowException
条目。在这种情况下,它只会显示该条目的第30行而不是第34行