mirror of
https://github.com/ICDSystems/ICD.Common.Utils.git
synced 2026-02-14 20:25:01 +00:00
feat: timer rescheduling, abstract scheduled action, datetime and dayofweek extensions
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using ICD.Common.Utils.EventArguments;
|
||||
using ICD.Common.Utils.Extensions;
|
||||
|
||||
namespace ICD.Common.Utils.Services.Scheduler
|
||||
{
|
||||
public abstract class AbstractScheduledAction : IScheduledAction
|
||||
{
|
||||
public event EventHandler OnScheduledRunTimeChanged;
|
||||
|
||||
private DateTime? m_NextRunTime;
|
||||
|
||||
public DateTime? NextRunTime
|
||||
{
|
||||
get { return m_NextRunTime; }
|
||||
private set
|
||||
{
|
||||
if (m_NextRunTime == value)
|
||||
return;
|
||||
|
||||
m_NextRunTime = value;
|
||||
|
||||
OnScheduledRunTimeChanged.Raise(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
RunFinal();
|
||||
NextRunTime = UpdateRunTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs when the action has hit its scheduled time
|
||||
/// </summary>
|
||||
public abstract void RunFinal();
|
||||
|
||||
/// <summary>
|
||||
/// Runs after RunFinal in order to set the next run time of this action
|
||||
/// </summary>
|
||||
public abstract DateTime? UpdateRunTime();
|
||||
}
|
||||
}
|
||||
@@ -24,16 +24,10 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (IScheduledAction action in m_Actions)
|
||||
{
|
||||
Unsubscribe(action);
|
||||
Clear();
|
||||
|
||||
IDisposable disposable = action as IDisposable;
|
||||
if (disposable != null)
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
m_Actions.Clear();
|
||||
m_Timer.Stop();
|
||||
m_Timer.Dispose();
|
||||
}
|
||||
|
||||
#region Methods
|
||||
@@ -50,6 +44,8 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
{
|
||||
m_CriticalSection.Leave();
|
||||
}
|
||||
|
||||
RescheduleTimer();
|
||||
}
|
||||
|
||||
public void Remove(IScheduledAction action)
|
||||
@@ -64,6 +60,28 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
{
|
||||
m_CriticalSection.Leave();
|
||||
}
|
||||
|
||||
RescheduleTimer();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_CriticalSection.Enter();
|
||||
try
|
||||
{
|
||||
foreach (IScheduledAction action in m_Actions)
|
||||
{
|
||||
Unsubscribe(action);
|
||||
}
|
||||
|
||||
m_Actions.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_CriticalSection.Leave();
|
||||
}
|
||||
|
||||
RescheduleTimer();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@@ -105,15 +123,25 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
}
|
||||
}
|
||||
|
||||
RescheduleTimer();
|
||||
}
|
||||
|
||||
private void RescheduleTimer()
|
||||
{
|
||||
// enter again to check the closest next run time
|
||||
m_CriticalSection.Enter();
|
||||
try
|
||||
{
|
||||
var action = m_Actions.FirstOrDefault();
|
||||
if (action == null)
|
||||
var action = m_Actions.FirstOrDefault(a => a.NextRunTime != null);
|
||||
if (action == null || action.NextRunTime == null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_Timer.Reset((long)(DateTime.Now - action.NextRunTime).TotalMilliseconds);
|
||||
long msToNextAction = (long)(DateTime.Now - action.NextRunTime.Value).TotalMilliseconds;
|
||||
long timerDueTime = Math.Min(msToNextAction, MAX_TIMER_INTERVAL);
|
||||
m_Timer.Reset(timerDueTime);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -169,6 +197,8 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
{
|
||||
m_CriticalSection.Leave();
|
||||
}
|
||||
|
||||
RescheduleTimer();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using ICD.Common.Utils.EventArguments;
|
||||
|
||||
namespace ICD.Common.Utils.Services.Scheduler
|
||||
{
|
||||
@@ -12,7 +13,7 @@ namespace ICD.Common.Utils.Services.Scheduler
|
||||
/// <summary>
|
||||
/// Gets the next time this action should be run
|
||||
/// </summary>
|
||||
DateTime NextRunTime { get; }
|
||||
DateTime? NextRunTime { get; }
|
||||
|
||||
void Run();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user