سؤال

كجزء من معالجة بعض الأخطاء في منتجنا، نود تفريغ بعض معلومات تتبع المكدس.ومع ذلك، فإننا نلاحظ أن العديد من المستخدمين سيلتقطون لقطة شاشة لمربع حوار رسالة الخطأ بدلاً من إرسال نسخة من التقرير الكامل المتوفر من البرنامج إلينا، وبالتالي أرغب في توفير الحد الأدنى من معلومات تتبع المكدس في مربع الحوار هذا.

يبدو تتبع مكدس .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، لديك طريقة لمستويات السجل المختلفة، ولكل منها معلمة استثناء.لذلك، عندما تقوم بتمرير الاستثناء الثاني، فإنه سيتم طباعة تتبع المكدس إلى أي مُلحق قمت بتكوينه.

مثال: 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