Files
Yaulw/Thread/SingleThreadTimer.cs
2016-02-15 12:32:26 -05:00

144 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
namespace Yaulw.Thread
{
/// <summary>
/// Single Threaded Timer * only calls the elapsed event handler once and only
/// will call it again, if the elapsed event handler returns
/// </summary>
public class SingleThreadTimer
{
#region Private Members
private STElapsedEventHandler _elapsedHandler = null;
private uint _IntervalMilliseconds = 0;
private System.Threading.Thread _thread = null;
#endregion
#region Construction
/// <summary>
/// Creates a new Single-threaded System.Timer
/// </summary>
/// <param name="ElapsedHandler">Event Handler for Timer</param>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
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
/// <summary>
/// Main DoWork() Function, calls the ElapsedHandler at every interval
/// * Single threaded * ElapsedHandler will only get called again, once it returns
/// </summary>
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
/// <summary>
/// ElapsedEvent Handler is called when the time interval elapsed
/// </summary>
/// <param name="sender">Sends the STimer Object</param>
/// <param name="e">sends the Timestampe when the interval elapsed</param>
public delegate void STElapsedEventHandler(object sender, STElapsedEventArgs e);
/// <summary>
/// ElapsedEventArgs are called with the time stamp when the Event was raised
/// </summary>
public class STElapsedEventArgs : EventArgs
{
public DateTime SignalTime { get; private set; }
public STElapsedEventArgs(DateTime SignalTime) { this.SignalTime = SignalTime; }
}
#endregion
#region Public Methods
/// <summary>
/// Manually Start the STimer
/// </summary>
public bool Start()
{
Stop(); // First Stop(), an existing Timer
return Start(_IntervalMilliseconds);
}
/// <summary>
/// Manually Start the STimer at a new Interval
/// </summary>
/// <param name="tsInterval">Interval as a TimeSpan</param>
public bool Start(TimeSpan tsInterval)
{
Stop(); // First Stop(), an existing Timer
return Start((uint)tsInterval.TotalMilliseconds);
}
/// <summary>
/// Manually Start the STimer at a new Interval
/// </summary>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
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;
}
/// <summary>
/// Manually Stop the STimer
/// </summary>
public void Stop()
{
try
{
if (_thread != null)
_thread.Abort();
}
catch (Exception) { /* ignore */ }
_thread = null;
}
#endregion
}
}