RunnableSessionToken.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Collections.Concurrent;
  2. namespace Terminal.Gui.App;
  3. /// <summary>
  4. /// Represents a running session created by <see cref="IApplication.Begin(IRunnable)"/>.
  5. /// Wraps an <see cref="IRunnable"/> instance and is stored in <see cref="IApplication.RunnableSessionStack"/>.
  6. /// </summary>
  7. public class RunnableSessionToken : IDisposable
  8. {
  9. internal RunnableSessionToken (IRunnable runnable) { Runnable = runnable; }
  10. /// <summary>
  11. /// Gets or sets the runnable associated with this session.
  12. /// Set to <see langword="null"/> by <see cref="IApplication.End(RunnableSessionToken)"/> when the session completes.
  13. /// </summary>
  14. public IRunnable? Runnable { get; internal set; }
  15. /// <summary>
  16. /// Releases all resource used by the <see cref="RunnableSessionToken"/> object.
  17. /// </summary>
  18. /// <remarks>
  19. /// <para>
  20. /// Call <see cref="Dispose()"/> when you are finished using the <see cref="RunnableSessionToken"/>.
  21. /// </para>
  22. /// <para>
  23. /// <see cref="Dispose()"/> method leaves the <see cref="RunnableSessionToken"/> in an unusable state. After
  24. /// calling
  25. /// <see cref="Dispose()"/>, you must release all references to the <see cref="RunnableSessionToken"/> so the
  26. /// garbage collector can
  27. /// reclaim the memory that the <see cref="RunnableSessionToken"/> was occupying.
  28. /// </para>
  29. /// </remarks>
  30. public void Dispose ()
  31. {
  32. Dispose (true);
  33. GC.SuppressFinalize (this);
  34. #if DEBUG_IDISPOSABLE
  35. WasDisposed = true;
  36. #endif
  37. }
  38. /// <summary>
  39. /// Releases all resource used by the <see cref="RunnableSessionToken"/> object.
  40. /// </summary>
  41. /// <param name="disposing">If set to <see langword="true"/> we are disposing and should dispose held objects.</param>
  42. protected virtual void Dispose (bool disposing)
  43. {
  44. if (Runnable is { } && disposing)
  45. {
  46. // Runnable must be null before disposing
  47. throw new InvalidOperationException (
  48. "Runnable must be null before calling RunnableSessionToken.Dispose"
  49. );
  50. }
  51. }
  52. #if DEBUG_IDISPOSABLE
  53. #pragma warning disable CS0419 // Ambiguous reference in cref attribute
  54. /// <summary>
  55. /// Gets whether <see cref="RunnableSessionToken.Dispose"/> was called on this RunnableSessionToken or not.
  56. /// For debug purposes to verify objects are being disposed properly.
  57. /// Only valid when DEBUG_IDISPOSABLE is defined.
  58. /// </summary>
  59. public bool WasDisposed { get; private set; }
  60. /// <summary>
  61. /// Gets the number of times <see cref="RunnableSessionToken.Dispose"/> was called on this object.
  62. /// For debug purposes to verify objects are being disposed properly.
  63. /// Only valid when DEBUG_IDISPOSABLE is defined.
  64. /// </summary>
  65. public int DisposedCount { get; private set; }
  66. /// <summary>
  67. /// Gets the list of RunnableSessionToken objects that have been created and not yet disposed.
  68. /// Note, this is a static property and will affect all RunnableSessionToken objects.
  69. /// For debug purposes to verify objects are being disposed properly.
  70. /// Only valid when DEBUG_IDISPOSABLE is defined.
  71. /// </summary>
  72. public static ConcurrentBag<RunnableSessionToken> Instances { get; } = [];
  73. /// <summary>Creates a new RunnableSessionToken object.</summary>
  74. public RunnableSessionToken () { Instances.Add (this); }
  75. #pragma warning restore CS0419 // Ambiguous reference in cref attribute
  76. #endif
  77. }