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
}
}