2008-09-09 153 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);