为什么处理操作的方法中的 catch 会截断堆栈跟踪

本文关键字:堆栈 跟踪 处理 操作 方法 为什么 catch | 更新日期: 2023-09-27 18:30:41

考虑这个小程序。忽略,如果你愿意的话,通用的捕获,我已经保持简短以试图说明这一点:

private static void Main(string[] args)
{
    Try(Fail);
}
private static void Fail()
{
    var x = ((string)null).Clone();
}
private static void Try(Action action)
{
    try
    {
        action();
    }
    catch (Exception exc)
    {
        Debug.WriteLine(exc.StackTrace);                
    }
}

运行时,将生成以下内容(删除了一些路径信息):

at Scratch.Program.Fail() in Program.cs:line 27
at Scratch.Program.Try(Action action) in Program.cs:line 34

我的问题是 - 为什么异常的堆栈跟踪停止在Try()方法上展开方法链?我希望它能超越它到Main()方法。

我无法找到任何关于阻止异常展开通过Try()的文档 - 所以我想了解这一点。

为什么处理操作的方法中的 catch 会截断堆栈跟踪

这个:

try
{
    action();
}
catch (Exception exc)
{
    Debug.WriteLine(exc.StackTrace);                
}

Try 中捕获您的异常,并且不会向上传播以展开调用堆栈,它只是吞下异常。因此,您不会看到Main作为堆栈跟踪的一部分。如果要查看Main,请将catch留给Main方法:

public static void Main(string[] args)
{
    try
    {
        Try(Fail);
    }
    catch (Exception e)
    {
    }
}

现在你看到:

at ConsoleApplication2.Program.Fail() in C:''Users''Yuval''documents''visual studio 14''项目''控制台应用程序2''控制台应用程序2''程序.cs:第 25 行 在控制台应用程序2.程序.尝试(操作操作) 在 C:''Users''Yuval''documents''visual studio 14''项目''控制台应用程序2''控制台应用程序2''程序.cs:第 30 行 at ConsoleApplication2.Program.Main(String[] args) in C:''Users''Yuval''documents''visual studio 14''项目''控制台应用程序2''控制台应用程序2''程序.cs:第 15 行

Exception.Stacktrace调用GetStackTrace最终会调用
new StackTrace(this /* exception object */, true) .与这些参数一起使用时,堆栈跟踪将针对异常点进行评估,直到当前方法为止。您可以在添加时自行检查

catch (Exception exc)
{
    Debug.WriteLine(new StackTrace());
    Debug.WriteLine(new StackTrace(exc, true));          
}

第二个版本是 exc.StackTrace 返回的堆栈跟踪,第一个是从当前方法到入口点或线程启动的完整堆栈跟踪。