TimeoutTimer.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //------------------------------------------------------------------------------
  2. // <copyright file="TimeoutTimer.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //
  6. // Class used to manage timeouts in complex system operations.
  7. //
  8. // <owner current="true" primary="true">[....]</owner>
  9. // <owner current="true" primary="false">[....]</owner>
  10. //------------------------------------------------------------------------------
  11. namespace System.Data.ProviderBase
  12. {
  13. using System;
  14. using System.Data.Common;
  15. using System.Diagnostics;
  16. // Purpose:
  17. // Manages determining and tracking timeouts
  18. //
  19. // Intended use:
  20. // Call StartXXXXTimeout() to get a timer with the given expiration point
  21. // Get remaining time in appropriate format to pass to subsystem timeouts
  22. // Check for timeout via IsExpired for checks in managed code.
  23. // Simply abandon to GC when done.
  24. internal class TimeoutTimer
  25. {
  26. //-------------------
  27. // Fields
  28. //-------------------
  29. private long _timerExpire;
  30. private bool _isInfiniteTimeout;
  31. //-------------------
  32. // Timeout-setting methods
  33. //-------------------
  34. // Get a new timer that will expire in the given number of seconds
  35. // For input, a value of zero seconds indicates infinite timeout
  36. internal static TimeoutTimer StartSecondsTimeout(int seconds)
  37. {
  38. //--------------------
  39. // Preconditions: None (seconds must conform to SetTimeoutSeconds requirements)
  40. //--------------------
  41. // Method body
  42. var timeout = new TimeoutTimer();
  43. timeout.SetTimeoutSeconds(seconds);
  44. //---------------------
  45. // Postconditions
  46. Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
  47. return timeout;
  48. }
  49. // Get a new timer that will expire in the given number of milliseconds
  50. // No current need to support infinite milliseconds timeout
  51. internal static TimeoutTimer StartMillisecondsTimeout(long milliseconds)
  52. {
  53. //--------------------
  54. // Preconditions
  55. Debug.Assert(0 <= milliseconds);
  56. //--------------------
  57. // Method body
  58. var timeout = new TimeoutTimer();
  59. timeout._timerExpire = checked(ADP.TimerCurrent() + (milliseconds * TimeSpan.TicksPerMillisecond));
  60. timeout._isInfiniteTimeout = false;
  61. //---------------------
  62. // Postconditions
  63. Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
  64. return timeout;
  65. }
  66. //-------------------
  67. // Methods for changing timeout
  68. //-------------------
  69. internal void SetTimeoutSeconds(int seconds)
  70. {
  71. //--------------------
  72. // Preconditions
  73. Debug.Assert(0 <= seconds || InfiniteTimeout == seconds); // no need to support negative seconds at present
  74. //--------------------
  75. // Method body
  76. if (InfiniteTimeout == seconds)
  77. {
  78. _isInfiniteTimeout = true;
  79. }
  80. else
  81. {
  82. // Stash current time + timeout
  83. _timerExpire = checked(ADP.TimerCurrent() + ADP.TimerFromSeconds(seconds));
  84. _isInfiniteTimeout = false;
  85. }
  86. //---------------------
  87. // Postconditions:None
  88. }
  89. //-------------------
  90. // Timeout info properties
  91. //-------------------
  92. // Indicator for infinite timeout when starting a timer
  93. internal static readonly long InfiniteTimeout = 0;
  94. // Is this timer in an expired state?
  95. internal bool IsExpired
  96. {
  97. get
  98. {
  99. return !IsInfinite && ADP.TimerHasExpired(_timerExpire);
  100. }
  101. }
  102. // is this an infinite-timeout timer?
  103. internal bool IsInfinite
  104. {
  105. get
  106. {
  107. return _isInfiniteTimeout;
  108. }
  109. }
  110. // Special accessor for TimerExpire for use when thunking to legacy timeout methods.
  111. internal long LegacyTimerExpire
  112. {
  113. get
  114. {
  115. return (_isInfiniteTimeout) ? Int64.MaxValue : _timerExpire;
  116. }
  117. }
  118. // Returns milliseconds remaining trimmed to zero for none remaining
  119. // and long.MaxValue for infinite
  120. // This method should be prefered for internal calculations that are not
  121. // yet common enough to code into the TimeoutTimer class itself.
  122. internal long MillisecondsRemaining
  123. {
  124. get
  125. {
  126. //-------------------
  127. // Preconditions: None
  128. //-------------------
  129. // Method Body
  130. long milliseconds;
  131. if (_isInfiniteTimeout)
  132. {
  133. milliseconds = long.MaxValue;
  134. }
  135. else
  136. {
  137. milliseconds = ADP.TimerRemainingMilliseconds(_timerExpire);
  138. if (0 > milliseconds)
  139. {
  140. milliseconds = 0;
  141. }
  142. }
  143. //--------------------
  144. // Postconditions
  145. Debug.Assert(0<=milliseconds); // This property guarantees no negative return values
  146. return milliseconds;
  147. }
  148. }
  149. }
  150. }