Вопрос

В рамках обработки ошибок в нашем продукте мы хотели бы сбросить некоторую информацию трассировки стека.Однако мы сталкиваемся с тем, что многие пользователи просто делают снимок экрана диалогового окна сообщения об ошибке вместо того, чтобы отправлять нам копию полного отчета, доступного из программы, и поэтому я хотел бы сделать некоторую минимальную информацию о трассировке стека доступной в этом диалоговом окне.

Трассировка стека .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

Любой совет, который вы можете дать, будет полезен.

Это было полезно?

Решение

Вы сможете получить объект StackTrace вместо строки, сказав

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

Затем вы можете просмотреть фреймы самостоятельно, не полагаясь на форматирование платформы.

Смотрите также: Справочник по StackTrace

Другие советы

Вот код, который я использую для этого без исключения

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

Просто чтобы сделать это 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();
}

(на основе ответа Линдхольма)

Или есть еще более короткая версия..

Console.Write(exception.StackTrace);

В качестве альтернативы log4net, хотя и потенциально опасен, дал мне лучшие результаты, чем System.Diagnostics.По сути, в log4net у вас есть метод для различных уровней журнала, каждый из которых имеет параметр Exception.Итак, когда вы передаете второе исключение, оно печатает трассировку стека в любое настроенное вами приложение.

пример: 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
   ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top