2008-09-09 14 views
50

W ramach niektórych błędów obsługi naszych produktów chcielibyśmy zrzucić pewne informacje śledzenia stosu. Jednak mamy wrażenie, że wielu użytkowników po prostu zrobi zrzut ekranu okna dialogowego z komunikatem o błędzie, zamiast wysłać nam kopię pełnego raportu dostępnego z programu, a tym samym chciałbym udostępnić w tym oknie dialogowym kilka minimalnych informacji śledzenia stosu.Informacje dotyczące śledzenia stosu wydruku z C#

NET stos ślad na moim komputerze wygląda następująco:

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 

Mam to pytanie:

Format wygląda na to:

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

Jednak at i w w słowach kluczowych, zakładam, że będą one zlokalizowane, jeśli uruchomią, powiedzmy, norweski .NET runtime i Poniżej angielskiej wersji, którą zainstalowałem.

Czy istnieje sposób dla mnie, aby wybrać ten ślad stosu w sposób neutralny językowo, tak, że mogę wyświetlić tylko plik i numer linii dla tych wpisów, które to mają?

Innymi słowy, chciałbym tej informacji od powyższego tekstu:

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

Wszelkie porady można dać będzie pomocne.

+1

Życzę ktoś dałby odpowiedź analizowania tego, jak pracuję z zapisanymi strun z dowolnych aplikacji i naprawdę chciałem uzyskać trochę szczegółów na ten temat.Biorąc pod uwagę, że masz kontrolę nad źródłem StackTrace, rzeczywiście wybrałeś poprawną odpowiedź :) – TheXenocide

Odpowiedz

70

powinny być w stanie uzyskać obiekt StackTrace zamiast napisu mówiąc

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

Następnie można spojrzeć na siebie klatek bez polegania na formatowanie tych ram.

Zobacz także: StackTrace reference

+0

Oooh, miłe, nie wiedziałem o tym! Na pewno się tym zajrzę. –

+0

Czy w trybie zwolnienia nadal można uzyskać wyjątek dotyczący stosu wyjątku? – erdogany

+0

Ssealizuję ** wyjątek ** w pliku. 'SerializationHelper.Serialize (@" c: \ temp \ ConfigurationErrorsExceptions.ser ", ex);' Jeśli deserializuję z pliku 'var exception = SerializationHelper.Deserialize (@" ConfigurationErrorsExceptions.ser ");' *** Trace *** jest _nie dostępny_ 'var trace = new System.Diagnostics.StackTrace (wyjątek jako wyjątek);' ** FrameCount ** to 0 – Kiquenet

0

Jako alternatywa, log4net, choć potencjalnie niebezpieczne, dał mi lepsze rezultaty niż System.Diagnostics. Zasadniczo w log4net, masz metodę dla różnych poziomów dziennika, każdy z parametrem wyjątku. Tak więc, gdy przekażesz drugi wyjątek, wydrukuje on ślad stosu do dowolnego skonfigurowanego appendera.

przykład: Logger.Error("Danger!!!", myException);

wyjście, w zależności od konfiguracji, wygląda mniej więcej tak

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

Czy możesz wyjaśnić, co masz na myśli mówiąc o tym, że log4net jest "potencjalnie niebezpieczny"? –

+0

Nie wiem na pewno, co Oglester miał na myśli, ale wiem, że stackoverflow.com miał pewne problemy z zakleszczeniem, ponieważ log4net logował wyjątki do bazy danych. Nie miałem żadnych osobistych problemów, ale utrzymuję to w prostocie i trzymam się toczących się plików tekstowych. –

+0

Jeśli nie odpowiednio zarządzasz swoimi referencjami, skończy się przeciek pamięci. Strona internetowa, nad którą pracowałem od dłuższego czasu, w znacznym stopniu korzysta z log4net (pliki toczące się). Ponieważ log4net odwołuje się do pliku (niebezpieczne), musisz mieć pewność, że odniesienia do log4net zostaną wyczyszczone lub zminimalizowane. –

27

Oto kod używam to zrobić bez wyjątku

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)); 
    } 
} 
+0

Można by pomyśleć, że zostałoby to wbudowane w funkcjonalność, skoro obsługa wyjątków robi to natywnie. –

18

Właśnie zrobić to 15-sekundowa odpowiedź na kopiowanie i wklejanie:

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(); 
} 

(na podstawie Lindholm odpowiedź)

+3

Dzięki za to. Zauważ, że możesz użyć sb.AppendLine (...), aby uniknąć zakodowania znaku końca linii. –

+0

prawda. zaktualizowane ... –

8

Albo jest jeszcze krótsza wersja ..

Console.Write(exception.StackTrace);