Before anyone flips out on me about singletons, I will say that in this instance it makes sense for me to have a singleton given the wide use of this object throughout my code and if someone has a better way short of DI I would like to hear but I would hope that this would not be the focus of this post, moreso helping solve it would be.
That being said here's the issue: It seems after a given amount of time that I am losing a reference to my class scheduler and inside there is a timer tick that no longer fires. Is this because it is being used in a singleton fashion and once it loses a reference it is GC'd?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace MessageQueueInterface
{
public class Scheduler
{
private const int _interval = 1000;
private readonly Dictionary<DateTime, Action> _scheduledTasks = new Dictionary<DateTime, Action>();
private readonly Timer _mainTimer;
public Scheduler()
{
_mainTimer = new Timer();
_mainTimer.Interval = _interval;
_mainTimer.Tick += MainTimer_Tick;
_mainTimer.Start();
}
void MainTimer_Tick(object sender, EventArgs e)
{
CheckStatus();
}
public void Add(DateTime timeToFire, Action action)
{
lock (_scheduledTasks)
{
if (!_scheduledTasks.Keys.Contains(timeToFire))
{
_scheduledTasks.Add(timeToFire, action);
}
}
}
public void CheckStatus()
{
Dictionary<DateTime, Action> scheduledTasksToRemove = new Dictionary<DateTime, Action>();
lock (_scheduledTasks)
{
foreach (KeyValuePair<DateTime, Action> scheduledTask in _scheduledTasks)
{
if (DateTime.Now >= scheduledTask.Key)
{
scheduledTask.Value.Invoke();
scheduledTasksToRemove.Add(scheduledTask.Key, scheduledTask.Value);
}
}
}
foreach (KeyValuePair<DateTime, Action> pair in scheduledTasksToRemove)
{
_scheduledTasks.Remove(pair.Key);
}
}
}
}
it is accessed in the following way in other classes
ApplicationContext.Current.Scheduler.Add(DateTime.Now.AddSeconds(1), ResetBackColor);
ApplicationContext
is my singleton
also i am aware that a datetime object is not the best KEY for a dictionary, but it suits my purposes here
here's the singleton
public class ApplicationContext
{
private static ApplicationContext _context;
private Scheduler _scheduler;
public Scheduler Scheduler
{
get { return _scheduler; }
}
private void SetProperties()
{
_scheduler = new Scheduler();
}
public static ApplicationContext Current
{
get
{
if (_context == null)
{
_context = new ApplicationContext();
_context.SetProperties();
}
return _context;
}
}
}