Pregunta

Como parte del manejo de errores en nuestro producto, nos gustaría volcar información de seguimiento de la pila.Sin embargo, experimentamos que muchos usuarios simplemente toman una captura de pantalla del cuadro de diálogo del mensaje de error en lugar de enviarnos una copia del informe completo disponible en el programa y, por lo tanto, me gustaría que alguna información mínima de seguimiento de la pila esté disponible en este cuadro de diálogo.

Un seguimiento de la pila .NET en mi máquina se ve así:

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

Tengo esta pregunta:

El formato parece ser este:

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

sin embargo, el en y en palabras clave, supongo que se localizarán si ejecutan, digamos, un entorno de ejecución .NET noruego en lugar del inglés que he instalado.

¿Hay alguna forma de separar este seguimiento de pila de manera neutral en cuanto al idioma, de modo que pueda mostrar solo el archivo y el número de línea de aquellas entradas que lo tienen?

En otras palabras, me gustaría obtener esta información del texto anterior:

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

Cualquier consejo que puedas dar será útil.

¿Fue útil?

Solución

Debería poder obtener un objeto StackTrace en lugar de una cadena diciendo

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

Luego podrá ver los marcos usted mismo sin depender del formato del marco.

Ver también: Referencia de StackTrace

Otros consejos

Aquí está el código que uso para hacer esto sin excepción.

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

Sólo para hacer de esta una respuesta de copiar y pegar de 15 segundos:

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

(basado en la respuesta de Lindholm)

O hay una versión incluso más corta.

Console.Write(exception.StackTrace);

Como alternativa, log4net, aunque potencialmente peligroso, me ha dado mejores resultados que System.Diagnostics.Básicamente, en log4net, tiene un método para los distintos niveles de registro, cada uno con un parámetro de excepción.Entonces, cuando pase la segunda excepción, imprimirá el seguimiento de la pila en cualquier agregado que haya configurado.

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

La salida, dependiendo de la configuración, se parece a

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
   ...
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top