c# - catch(Exception ex) 会丢掉StackTrace 是怎么回事?
Posted 蒙蒙大川
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# - catch(Exception ex) 会丢掉StackTrace 是怎么回事?相关的知识,希望对你有一定的参考价值。
原本这篇文章就想写写StackTrace怎么会丢的问题, 但现在的内容变成了讨论怎么处理Exception的问题。
该不该用try catch, 什么时候用?也困扰了我很久, 好像随便写写就可以, 但是事实上还是有Best Practise, 以下内容请您参考,欢迎指正!
StackTrace: 保存方法的栈调用信息。
什么意思呢?A方法里调用了B方法,B方法里调用了C方法,你调用A方法的时候StackTrace里就大概是这样:
at Project.Class.C in c:\aaa\Project\class.cs:line 10.
at Project.Class.B in c:\aaa\Project\class.cs:line 20.
at Project.Class.A in c:\aaa\Project\class.cs:line 30.
它就是个字符串。
不过他有什么用呢?你说呢,毕竟人家连行号都告诉你了。如果丢了StackTrace,我们也就丢了这些信息。
什么情况下会丢StackTrace?看看这段代码:
- static void Main(string[] args)
- {
- try
- {
- // Call Method1
- Console.WriteLine(Method1());
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.StackTrace);
- }
- Console.ReadLine();
- }
- public static int Method1()
- {
- try
- {
- return Method1_1();
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- public static int Method1_1()
- {
- int j = 0;
- return 10 / j;
- }
乍看貌似没有什么问题,但是Method1多做了一件事: Catch(Exception ex){thorw ex;}
他带来一个后果就是,StackStace会丢.
得到的StackTrace如下:
at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 33
at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16
删除 try..catch, 我们得到的StackTrace如下:
at ExceptionMethodCall.Program.Method1_1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 40
at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 29
at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16
结果显而易见。
更多:
如果Method1代码这么写:
- public static int Method1()
- {
- try
- {
- return Method1_1();
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- throw;
- }
- }
会发生什么?
注意:这次没有throw ex, 而是 throw.
我们发现StackTrace又不会丢了:
at ExceptionMethodCall.Program.Method1_1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 40
at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 29
at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16
原因是什么?
我就随便说说我的想法, 你这么想也行 不这么想也行, 但是我不负责哦:
catch(Exception ex) 会实例化一个Exception 对象,其实就是在此处你catch到的这个Exception。你怎么处理它都可以, 写log或者Print出来,
但是你就是不要throw 它。 你throw它了,exception stack就被清空。没有throw 它, exception stack里就始终保存所有exceptions。
在更多:
如果Method1这么写:
- public static int Method1()
- {
- return Method1_1();
- }
注意:没有写任何try.. catch. 可能有人觉得会丢StackTrace, 事实上不会. 这里Method1() call Method1_1(), 它会完整的保存StackTrace。
事实上,你写更多层都没有关系, StackTrace依然很完整。
所以综上所述:
1. 如非必要, 不要给方法加任何try.. catch.., 只在调用方法的最外层处理Exception;
2. 如果需要在方法里处理Exception, 你直接catch(Exception ex)处理就好了, 不要throw ex;
以上是关于c# - catch(Exception ex) 会丢掉StackTrace 是怎么回事?的主要内容,如果未能解决你的问题,请参考以下文章
在我的 C# 代码中显示错误“前一个 catch 子句已经捕获了这个或超类型 `System.Exception' 的所有异常”
C# try catch finally 里面写Exception e是为啥?这个e有啥用?Exception e能改成别的吗?