La soluzione migliore che ho trovato è scrivere il callstack Exception
su Debug.Console
e lasciare che il parser della riga di codice incorporato in Visual Studio fornisca la navigazione.
ho trovato davvero utile quando si tratta di eccezioni non gestite sul AppDomain e WPF Dispatcher come Visual Studio si rompe sempre troppo tardi.
base da un articolo su Code Project, ho modificato è che emetta al Console come un singolo blocco di testo - anziché linea per linea - che era necessario ho registrazione anche iscritto Console.
Uso
public void ReportException(Exception exception)
{
if (Debugger.IsAttached)
{
DebugHelper.PrintExceptionToConsole(exception);
Debugger.Break();
}
// ...
}
Fonte
public static class DebugHelper
{
// Original idea taken from the CodeProject article
// http://www.codeproject.com/Articles/21400/Navigating-Exception-Backtraces-in-Visual-Studio
private static readonly string StarSeparator = new String('*', 80);
private static readonly string DashSeparator = new String('-', 80);
private const string TabString = " ";
/// <summary>
/// Prints the exception using a format recognized by the Visual Studio console parser.
/// Allows for quick navigation of exception call stack.
/// </summary>
/// <param name="exception">The exception.</param>
public static void PrintExceptionToConsole(Exception exception)
{
using (var indentedTextWriter = new IndentedTextWriter(Console.Out, TabString))
{
var indentLevel = 0;
while (exception != null)
{
indentedTextWriter.Indent = indentLevel;
indentedTextWriter.Write(FormatExceptionForDebugLineParser(exception));
exception = exception.InnerException;
indentLevel++;
}
}
}
private static string FormatExceptionForDebugLineParser(Exception exception)
{
StringBuilder result = new StringBuilder();
result.AppendLine(StarSeparator);
result.AppendLineFormat(" {0}: \"{1}\"", exception.GetType().Name, exception.Message);
result.AppendLine(DashSeparator);
// Split lines into method info and filename/line number
string[] lines = exception.StackTrace.Split(new string[] { " at " }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.Where(x => !String.IsNullOrEmpty(x))
.ToArray();
foreach (var line in lines)
{
string[] parts = line.Split(new string[] { " in " }, StringSplitOptions.RemoveEmptyEntries);
string methodInfo = parts[0];
if (parts.Length == 2)
{
string[] subparts = parts[1].Split(new string[] { ":line " }, StringSplitOptions.RemoveEmptyEntries);
result.AppendLineFormat(" {0}({1},1): {2}", subparts[0], Int32.Parse(subparts[1]), methodInfo);
}
else
result.AppendLineFormat(" {0}", methodInfo);
}
result.AppendLine(StarSeparator);
return result.ToString();
}
}
Per utilizzare il come è, sarà necessario anche il metodo di cui sopra, di estensione sotto e aggiungere lo spazio dei nomi System.CodeDom.Compiler
per IndentedTextWriter
.
Metodo di estensione
/// <summary>
/// Appends the string returned by processing a composite format string followed by the default line terminator.
/// </summary>
/// <param name="sb">The StringBuilder.</param>
/// <param name="format">The format.</param>
/// <param name="args">The args.</param>
public static void AppendLineFormat(this StringBuilder sb, string format, params object[] args)
{
sb.AppendFormat(format, args);
sb.AppendLine();
}
possibile duplicato del [C# rigenerare un'eccezione: come ottenere lo stack eccezione nel IDE] (http://stackoverflow.com/questions/4351333/c-sharp-rethrow-an-exception-how-to-get-the-exception-stack-in-the-ide) –