using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; namespace Yaulw.Thread { /// /// Single Threaded Timer * only calls the elapsed event handler once and only /// will call it again, if the elapsed event handler returns /// public class SingleThreadTimer { #region Private Members private STElapsedEventHandler _elapsedHandler = null; private uint _IntervalMilliseconds = 0; private System.Threading.Thread _thread = null; #endregion #region Construction /// /// Creates a new Single-threaded System.Timer /// /// Event Handler for Timer /// Interval in Miliseconds /// True to start the timer upon creation, false otherwise /// A Timer Object, which should be Disposed by Caller public SingleThreadTimer(STElapsedEventHandler ElapsedHandler, uint IntervalMilliseconds, bool StartEnabled) { _elapsedHandler = ElapsedHandler; _IntervalMilliseconds = IntervalMilliseconds; if (_elapsedHandler == null || _IntervalMilliseconds == 0) throw new ArgumentException("Invalid ElapsedHandler or Milliseconds. ElapsedHandler can not be null. Milliseconds can not be 0."); if (StartEnabled) Start(); } #endregion #region Private Helpers /// /// Main DoWork() Function, calls the ElapsedHandler at every interval /// * Single threaded * ElapsedHandler will only get called again, once it returns /// private void STimerThreadMethod() { do { if (_IntervalMilliseconds > 0) System.Threading.Thread.Sleep((int)_IntervalMilliseconds); if (_elapsedHandler != null) _elapsedHandler(this, new STElapsedEventArgs(DateTime.Now)); } while (true); } #endregion #region Public Delegates /// /// ElapsedEvent Handler is called when the time interval elapsed /// /// Sends the STimer Object /// sends the Timestampe when the interval elapsed public delegate void STElapsedEventHandler(object sender, STElapsedEventArgs e); /// /// ElapsedEventArgs are called with the time stamp when the Event was raised /// public class STElapsedEventArgs : EventArgs { public DateTime SignalTime { get; private set; } public STElapsedEventArgs(DateTime SignalTime) { this.SignalTime = SignalTime; } } #endregion #region Public Methods /// /// Manually Start the STimer /// public bool Start() { Stop(); // First Stop(), an existing Timer return Start(_IntervalMilliseconds); } /// /// Manually Start the STimer at a new Interval /// /// Interval as a TimeSpan public bool Start(TimeSpan tsInterval) { Stop(); // First Stop(), an existing Timer return Start((uint)tsInterval.TotalMilliseconds); } /// /// Manually Start the STimer at a new Interval /// /// Interval in Miliseconds public bool Start(uint IntervalMiliseconds) { try { Stop(); // First Stop(), an existing Timer if (IntervalMiliseconds > 0) _IntervalMilliseconds = IntervalMiliseconds; if (_thread == null) _thread = TStarter.StartThread(STimerThreadMethod, ("STimer-" + _elapsedHandler.Method.Name), System.Threading.ApartmentState.MTA, false, System.Threading.ThreadPriority.Normal); return ((_thread != null) && (_thread.IsAlive)); } catch (Exception) { /* ignore */ } return false; } /// /// Manually Stop the STimer /// public void Stop() { try { if (_thread != null) _thread.Abort(); } catch (Exception) { /* ignore */ } _thread = null; } #endregion } }