Bra*_*ann 25 .net c# exception-handling exception stack-trace
我一直认为"throw"和"throw ex"之间的区别在于单独抛出并没有重置异常的堆栈跟踪.
不幸的是,这不是我正在经历的行为; 这是一个复制我的问题的简单示例:
using System;
using System.Text;
namespace testthrow2
{
class Program
{
static void Main(string[] args)
{
try
{
try
{
throw new Exception("line 14");
}
catch (Exception)
{
throw; // line 18
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这段代码能够从第14行开始打印一个callstack; 然而,callstack从第18行开始.当然,它在样本中没什么大不了的,但在我的实际应用中,丢失初始错误信息是非常痛苦的.
我错过了一些明显的东西吗 有没有其他方法来实现我想要的(即重新抛出异常而不丢失堆栈信息?)
我正在使用.net 3.5
Jus*_*tin 34
你应该阅读这篇文章:
简而言之,throw
通常会保留原始抛出异常的堆栈跟踪,但前提是当前堆栈帧(即方法)中没有发生异常.
PreserveStackTrace
您使用的方法(在博客文章中显示)保留了原始堆栈跟踪,如下所示:
try
{
}
catch (Exception ex)
{
PreserveStackTrace(ex);
throw;
}
Run Code Online (Sandbox Code Playgroud)
但我通常的解决方案是要么不捕获并重新抛出这样的异常(除非绝对必要),要么只是总是使用InnerException
属性抛出新的异常来传播原始异常:
try
{
}
catch (Exception ex)
{
throw new Exception("Error doing foo", ex);
}
Run Code Online (Sandbox Code Playgroud)
问题是Windows正在重置堆栈的起点.CLR的行为与预期一致 - 这只是主机操作系统异常处理支持的限制.问题是每个方法调用只能有一个堆栈帧.
您可以将异常处理例程提取到单独的"帮助程序"方法中,这可以解决Windows SEH所施加的限制,但我认为这不一定是个好主意.
在不丢失堆栈信息的情况下重新抛出异常的正确方法是抛出一个新异常,并将原始的捕获异常作为内部异常包含在内.
很难想象很多情况下你真的需要这样做.如果你没有处理异常,只是抓住它来重新抛出它,你可能不应该首先捕获它.
归档时间: |
|
查看次数: |
7102 次 |
最近记录: |