2016-05-08 77 views
2

Ich möchte Universal Logger implementieren, die mir helfen Call-Stack der Methoden zu sehen.Get stacktrace in C# Methode

Ich weiß, es gibt einige Methoden von System.Diagnostic, aber sie wurden in. NET 4.0 eingeführt und ich fürchte, es wird nicht auf Xamarin oder .net-Core oder so ähnlich. Also möchte ich eine universellere Lösung haben.

Ein weiteres Problem ist async \ erwarten, die einige Unordnung einführen.

Ich durch über zusätzliche Parameter in jeder Methode übergeben, die einige Kontext speichern und mir helfen, Call-Stack zu bestimmen, aber diese Lösung ist ein bisschen komplex.

Auch ich kann Thread-Stack-Speicher mit unsicheren Code lesen und Call-Stack von mir selbst überprüfen, aber es ist nicht zuverlässig.

Gibt es noch eine andere Lösung?

+1

Man könnte es sicherlich Hack um: eine Ausnahme werfen, fangen ihn und las aus Aufrufliste it :) – MarcinJuraszek

+0

@MarcinJuraszek Nizza Hack :) aber ich fürchte, es Leistung zu viel beeinflussen. – Neir0

Antwort

2

Sie könnten einfach Environment.StackTrace verwenden. Das war von Anfang an Teil des Rahmens.

Environment.StackTrace wird den gesamten Stacktrace (einschließlich des Aufrufs an Environment.StackTrance selbst) als eine Zeile getrennte Zeichenfolge zurückgeben.

Etwas wie folgt aus:

bei System.Environment.GetStackTrace (Exception e, Boolean needFileInfo)
bei System.Environment.get_StackTrace()
bei WpfApplication2.MainWindow.GetStack (Int32 removeLines)
bei WpfApplication2.MainWindow.Button_Click (Object sender, RoutedEventArgs e)
...
bei System.Threading.ThreadHelper.ThreadStart()

Alles, was Sie tun müssen, ist Split/Pars/Format es, was auch immer Sie damit machen wollen.

Da Sie dies in Ihren eigenen Klassen verwenden werden, denken Sie daran, die neuesten X-Zeilen zu entfernen.

Dieser Code sollte überall funktionieren, da er bewusst Low-Level ist.

private static string[] GetStack(int removeLines) 
{ 
    string[] stack = Environment.StackTrace.Split(
     new string[] {Environment.NewLine}, 
     StringSplitOptions.RemoveEmptyEntries); 

    if(stack.Length <= removeLines) 
     return new string[0]; 

    string[] actualResult = new string[stack.Length - removeLines]; 
    for (int i = removeLines; i < stack.Length; i++) 
     // Remove 6 characters (e.g. " at ") from the beginning of the line 
     // This might be different for other languages and platforms 
     actualResult[i - removeLines] = stack[i].Substring(6); 

    return actualResult; 
} 
+0

Perfekt. Das funktioniert! – Neir0

+1

Eine Anmerkung, .net hat verschiedene Stack-Trace-Ausgabe für verschiedene Sprachen, so ist es notwendig, vorsichtig zu sein, während Sie "at" und andere sprachabhängige Wörter entfernen. – Neir0

+0

Guter Gedanke. Ich werde das in die Antwort für zukünftige Referenz aufnehmen. –