什么会导致 throw 重置调用堆栈(我使用的是“ throw”,而不是“ throw ex”)

2024-02-02

我一直觉得“扔”和“扔前”有什么区别单独的 throw 并没有重置异常的堆栈跟踪。 https://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-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();
        }
    }
}

我希望这段代码从第 14 行开始打印一个调用堆栈;然而,调用堆栈从第 18 行开始。当然,在示例中这没什么大不了的,但在我的实际应用程序中,丢失初始错误信息是相当痛苦的。

我错过了一些明显的事情吗?有没有另一种方法可以实现我想要的(即重新抛出异常而不丢失堆栈信息?)

我正在使用.net 3.5


你应该阅读这篇文章:

  • 重新抛出异常并保留完整的调用堆栈跟踪 http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx

简而言之,throw usually保留原始抛出异常的堆栈跟踪,但前提是该异常未在当前堆栈帧(即方法)中发生。

有一个方法PreserveStackTrace(在该博客文章中显示)您使用它来保留原始堆栈跟踪,如下所示:

try
{

}
catch (Exception ex)
{
    PreserveStackTrace(ex);
    throw;
}

但我通常的解决方案是要么简单地不捕获并重新抛出这样的异常(除非绝对必要),要么总是使用InnerException传播原始异常的属性:

try
{

}
catch (Exception ex)
{
     throw new Exception("Error doing foo", ex);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么会导致 throw 重置调用堆栈(我使用的是“ throw”,而不是“ throw ex”) 的相关文章

随机推荐