Callstack.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System;
  2. using System.Diagnostics;
  3. using System.Globalization;
  4. using System.Reflection;
  5. namespace WinSCP
  6. {
  7. internal class Callstack : IDisposable
  8. {
  9. public Callstack(Logger logger, object token = null)
  10. {
  11. _logger = logger;
  12. if (_logger.Logging)
  13. {
  14. _token = token;
  15. Type type = typeof(Callstack);
  16. StackTrace stackTrace = new StackTrace();
  17. int i = 0;
  18. MethodBase method;
  19. do
  20. {
  21. StackFrame frame = stackTrace.GetFrame(i);
  22. method = frame.GetMethod();
  23. if ((method.IsConstructor && ((method.DeclaringType == type) || method.DeclaringType.IsSubclassOf(type))) ||
  24. ((method.MemberType == MemberTypes.Method) && ((MethodInfo)method).ReturnType == type))
  25. {
  26. method = null;
  27. }
  28. else
  29. {
  30. break;
  31. }
  32. i++;
  33. }
  34. while (i < stackTrace.FrameCount);
  35. if (method != null)
  36. {
  37. _name = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", method.DeclaringType.Name, method.Name);
  38. if (_token != null)
  39. {
  40. _name += string.Format(CultureInfo.InvariantCulture, "({0})", _token);
  41. }
  42. _logger.WriteLine("{0} entering", _name);
  43. _logger.Indent();
  44. }
  45. }
  46. }
  47. public virtual void Dispose()
  48. {
  49. if (_name != null)
  50. {
  51. _logger.Unindent();
  52. _logger.WriteLine("{0} leaving", _name);
  53. }
  54. }
  55. private readonly Logger _logger;
  56. private readonly string _name;
  57. private readonly object _token;
  58. }
  59. }