/// <summary> /// stop previously started timer /// </summary> /// <param name="timer"> /// A <see cref="Timer"/> /// </param> /// <param name="timerId"> /// A <see cref="System.Int64"/> /// Value returned by StartTimer() /// Timer list reuse refernces (objects) of type Timer. Reference to Timer object /// is not enough to make sure that you stop the correct timer. Value timerId /// is a unique (system level) timer identifier /// </param> /// <returns> /// A <see cref="System.Boolean"/> /// Returns true if the timer was running and now stopped /// Call to this method for already stoped timer will return false /// and error message will be printed on the console /// </returns> public bool Stop(ITimer iTimer, long timerId) { Timers.Error error = Timers.Error.NONE; Timer timer = (Timer)iTimer; lock (this) { countStopAttempt++; if ((timer.Running) && (timer.TimerId == timerId)) { countStop++; timer.Running = false; } else if (!timer.Running) { error = Timers.Error.ALREADY_STOPED; } else if (timer.TimerId != timerId) { error = Timers.Error.STOP_UNKNOWN; } } if (error != Timers.Error.NONE) { PrintError("Stop failed ", error); } return(error == Timers.Error.NONE); }
protected void PrintError(string prefix, Timers.Error error) { System.Console.WriteLine(prefix + EnumUtils.GetDescription(error)); }
/// <summary> /// Allocate a free timer from the stack of free timers, set expiration /// add the timer to end of the list of running timers /// </summary> /// <param name="timeout"> /// A <see cref="System.Int64"/> /// </param> /// <param name="timer"> /// A <see cref="Timer"/> /// Reference to the started timer. Can be used in call to Stop() /// </param> /// <param name="timerId"> /// A <see cref="System.Int64"/> /// Timer list reuse refernces (objects) of type Timer. Reference to Timer is /// not enough to make sure that you stop the correct timer. Value timerId /// is a unique (system level) timer identifier /// </param> /// <param name="applicationHook"> /// A <see cref="System.Object"/> /// Timer.applicationHook field will be set to this value /// Field applicationHook can help to identify the timer in the context of timerExpired /// callback /// </param> /// <param name="autoRestart"> /// A <see cref="System.Boolean"/> /// If true the system will reschedule the expire timer automatically while taking care /// that the next expiration tick is exactly startTick+2*timeout /// </param> /// <returns> /// A <see cref="System.Boolean"/> /// returns true of Ok, false is failed to allocate a new timer - no free /// timers are available /// </returns> public bool Start(out ITimer iTimer, out long timerId, object applicationHook, bool autoRestart) { // timestamp the call as soon as possible DateTime startTime = DateTime.Now; long startTick = (startTime.Ticks) / TICKS_IN_MILLISECOND; Timer timer = null; iTimer = null; timerId = 0; Timers.Error error = Timers.Error.START_UNKNOWN; do { // get new timer Id timerId = TimerId.GetNext(); // allocate a timer from the stack of free timers lock (this) { countStartAttempt++; if (freeTimers.Count > 0) { timer = freeTimers.Pop(); } else { error = Timers.Error.NO_FREE_TIMERS; break; } } // initialize the timer timer.ApplicationHook = applicationHook; timer.StartTick = startTick; timer.ExpirationTime = startTick + Timeout; timer.Running = true; timer.TimerId = timerId; timer.AutoRestart = autoRestart; timer.Restarts = 1; // first start is considered a restart iTimer = timer; // add the timer to the queue of the pending timers lock (this) { countStart++; pendingTimers.Add(timer); countMax = Math.Max(countMax, pendingTimers.Count); } // send wakeup call to the task handling the timers timerTask.WakeupCall(); error = Timers.Error.NONE; }while (false); if (error != Timers.Error.NONE) { PrintError("Start failed ", error); } return(error == Timers.Error.NONE); }