2008-09-09 170 views
50

作为我们产品中某些错误处理的一部分,我们想转储一些堆栈跟踪信息。但是,我们体验到许多用户只会截取错误消息对话框的屏幕截图,而不是向我们发送程序中提供的完整报告的副本,因此我想在此对话框中提供一些最小的堆栈跟踪信息。从C#打印堆栈跟踪信息

我的机器上

.NET程序堆栈跟踪看起来是这样的:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) 
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) 
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize) 
at System.IO.StreamReader..ctor(String path) 
at LVKWinFormsSandbox.MainForm.button1_Click(Object sender, EventArgs e) in C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

我有这样的疑问:

格式看起来是这样的:

at <class/method> [in file:line ##] 

然而,关键字,我假设这些将被本地化,如果他们运行,比如说,一个挪威.NET运行时我而不是我已经安装的英文版本。

有没有什么办法让我以与语言无关的方式挑选这个堆栈跟踪,这样我就只能显示那些有这个条目的文件和行号?

换句话说,我想从上面的文字这样的信息:

C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

你可以给任何意见将是有益的。

+1

我想,因为我有记录的字符串从任意的应用工作会有人给出的答案解析,这和真的希望得到一些细节。鉴于你有控制StackTrace的来源,你确实已经选择了正确的答案:) – TheXenocide 2012-09-18 13:44:58

回答

70

你应该能够说

var trace = new System.Diagnostics.StackTrace(exception); 

然后你可以看一下框架自己不依赖框架的格式得到一个堆栈跟踪对象,而不是一个字符串。

参见:StackTrace reference

+0

Oooh,很好,我不知道!我一定会研究这个。 – 2008-09-09 13:55:18

+0

在发布模式下,你是否仍然能够精确地获取异常的堆栈跟踪? – erdogany 2009-03-16 09:15:24

+0

我在文件中序列化** exception **。 `SerializableHelper.Serialize(@“c:\ temp \ ConfigurationErrorsExceptions.ser”,ex);`如果我从文件反序列化`var exception = SerializationHelper.Deserialize(@“ConfigurationErrorsExceptions.ser”);`***跟踪***是_not available_`var trace = new System.Diagnostics.StackTrace(异常为Exception);`** FrameCount **为0 – Kiquenet 2015-10-13 09:58:01

0

作为替代,log4net的,但潜在的危险,给了我更好的结果比System.Diagnostics程序。基本上在log4net中,你有一个不同日志级别的方法,每个级别都有一个Exception参数。所以,当你传递第二个异常时,它会将堆栈跟踪打印到你已经配置的appender。

例如:Logger.Error("Danger!!!", myException);

输出,根据配置不同,看起来像

System.ApplicationException: Something went wrong. 
    at Adapter.WriteToFile(OleDbCommand cmd) in C:\Adapter.vb:line 35 
    at Adapter.GetDistributionDocument(Int32 id) in C:\Adapter.vb:line 181 
    ... 
+0

您能澄清一下您对log4net“有潜在危险”的含义吗? – 2008-09-09 13:33:44

27

这里是我用来做没有例外

public static void LogStack() 
{ 
    var trace = new System.Diagnostics.StackTrace(); 
    foreach (var frame in trace.GetFrames()) 
    { 
    var method = frame.GetMethod(); 
    if (method.Name.Equals("LogStack")) continue; 
    Log.Debug(string.Format("{0}::{1}", 
     method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, 
     method.Name)); 
    } 
} 
18

只是为了让代码这15秒复制粘贴答案:

static public string StackTraceToString() 
{ 
    StringBuilder sb = new StringBuilder(256); 
    var frames = new System.Diagnostics.StackTrace().GetFrames(); 
    for (int i = 1; i < frames.Length; i++) /* Ignore current StackTraceToString method...*/ 
    { 
     var currFrame = frames[i]; 
     var method = currFrame.GetMethod(); 
     sb.AppendLine(string.Format("{0}:{1}",      
      method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, 
      method.Name)); 
    } 
    return sb.ToString(); 
} 

(基于林霍尔姆答案)

8

或者有更短的版本..

Console.Write(exception.StackTrace);