StackTraceExtensionMethod.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. namespace VCommon.Diagnostics
  7. {
  8. public static class StackTraceExtensionMethod
  9. {
  10. /// <summary> 将堆栈跟踪信息格式化成每一帧都带程序集的详情文本, 可指定一个type来忽略之上的调用堆栈帧 </summary>
  11. public static string GetFormattedDetailStackTraceText(this StackTrace me, Type skipUpper = null, bool hasSourceStackFrameOnly = false)
  12. {
  13. var rawFrames = me.GetFrames();
  14. if (null == rawFrames) return null;
  15. var upperFrames = rawFrames;
  16. if (null != skipUpper)
  17. {
  18. var lst = new List<StackFrame>(rawFrames.Length);
  19. for (var i = rawFrames.Length - 1; i >= 0; i--)
  20. {
  21. if (rawFrames[i].GetMethod().DeclaringType == skipUpper) break;
  22. lst.Insert(0, rawFrames[i]);
  23. }
  24. upperFrames = lst.ToArray();
  25. }
  26. var sb = new StringBuilder();
  27. var filteredFrames = upperFrames;
  28. if (hasSourceStackFrameOnly)
  29. {
  30. filteredFrames = upperFrames.Where(p => p.HasSource()).ToArray();
  31. }
  32. foreach (var frame in filteredFrames)
  33. {
  34. var method = frame.GetMethod();
  35. var type = method.DeclaringType;
  36. var asm = type?.Assembly;
  37. var filename = frame.GetFileName();
  38. if (null != asm) sb.Append($"[{asm.GetName().Name}] ");
  39. if (null != type) sb.Append($"{type.FullName}::");
  40. sb.Append($"{method}");
  41. if (null != filename) sb.Append($" @ {filename}:{frame.GetFileLineNumber()},{frame.GetFileColumnNumber()}");
  42. sb.AppendLine();
  43. }
  44. return sb.ToString();
  45. }
  46. }
  47. }