C# 如何使用完整的调用堆栈记录异常?

C# 如何使用完整的调用堆栈记录异常?,c#,error-handling,elmah,callstack,C#,Error Handling,Elmah,Callstack,我想使用ELMAH来记录一个异常(不将它一直抛出调用堆栈),并记录整个调用堆栈 示例代码: protected void Page_Load(object sender, EventArgs e) { DoSomething(); } private void DoSomething() { try { TrySomething(); } catch (Exception ex) { LogExceptio

我想使用ELMAH来记录一个异常(不将它一直抛出调用堆栈),并记录整个调用堆栈

示例代码:

    protected void Page_Load(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void DoSomething()
    {
        try { TrySomething(); }
        catch (Exception ex) { LogException(ex); }
    }

    private void TrySomething()
    {
        throw new NotImplementedException();
    }

    public static void LogException(Exception ex)
    {
        var currentStack = new System.Diagnostics.StackTrace(true);
        Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    }
现在,在LogException方法中,我可以看到调用堆栈告诉我DoSomething()名为TrySomething(),这引发了异常,但我看不到调用堆栈告诉我Page_Load()名为DoSomething()。我希望能够看到完整的调用堆栈

LogException方法中ex.StackTrace的外观示例:

at WebApplication1._Default.TrySomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 26
at WebApplication1._Default.DoSomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 20
我可以从System.Diagnostics.StackTrace()获取完整的调用堆栈,例如:

at WebApplication1._Default.LogException(Exception ex)
at WebApplication1._Default.DoSomething()
at WebApplication1._Default.Page_Load(Object sender, EventArgs e)
[snip]
(通过遍历StackTrace的每一帧,我可以获得行号和源文件详细信息)


但是如何将其注入到异常中,或使用此调用堆栈细节引发新异常?有没有一种优雅的方法可以做到这一点?我错过了什么很明显的事情吗

当编译应用程序时没有调试标志,堆栈在执行时不一定保留。您只能通过向每个方法添加try/catch来保证记录每个项。

您是否查看了Exception.ToString()的结果?它包括一个堆栈跟踪。它是否包括您正在寻找的类型?

当出现错误时,您可以这样做以获得完整的堆栈:

var currentStack = new System.Diagnostics.StackTrace(true);
return currentStack.ToString();

你是说方法调用可以内联到执行序列中吗?否则我不确定我是否理解您的意思-必须保留调用堆栈!?是的,我认为它是内联的。Try/catch可以绕过它,或者总是在调试模式下构建。@Alex:他的意思是编译器(和JIT)经常通过内联方法优化代码(尽管可以使用methodimpl属性防止这种情况);在这种情况下,您将无法获得完整的堆栈跟踪。只有在发布模式下,我才将调试信息设置为pdb。我不知道编译器是否以某种方式标记了内联方法,从而可以对其进行分解/完全调试-这听起来是可能的。。无论如何,这个问题仍然与完全调试版本有关,其中完全调用堆栈肯定是可用的。任何进一步的帮助都将不胜感激。谢谢你。你完全正确,我刚刚阅读了有关代码在编译为优化(非调试,发布模式)时内联的内容,它没有显示在调用堆栈中。因此,它的使用显然是有限的。感谢againex.StackTrace是当前(内部)调用堆栈的字符串表示形式,但是它没有显示异常之外的堆栈。我将用ex.StackTrace的结果更新问题正文以及我的后续内容查看这些相关问题的答案,以便更好地理解为什么您没有获得完整的调用堆栈:以及