I'm creating a linked list of objects holding a time. the linked list is sorted by that time, which mean that the most early item would be first. with in the class holding the linked list i keep a timer that should operate always on the first item in the list. when the event of the timer is done, the first item is removed, and the timer restart with the interval set by the new first item's time. the same happened if an item with an earlier time than the first item is being inserted. the error: when i run the program with 2 items in the list the Elapsed event occurring 3 times, and therefore i get the error this
System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Collections.Generic.LinkedList.First.get returned null.
because the first item has been removed and the event try to print it's id. my question is why the third event happened in the first place, since the timer shouldn't be activated if there is no items in the list . this is the item class:
public class TimerItem : IComparable<TimerItem>
{
public int Id { get; }
private readonly DateTime ResultTime;
public TimerItem (int id, DateTime resultTime)
{
Id = id;
ResultTime = resultTime;
}
public double MilliSecondsCountToCompletion
{
get
{
if (ResultTime.Subtract(DateTime.Now).Seconds > 0)
{
return ResultTime.Subtract(DateTime.Now).TotalMilliseconds;
}
return 1;
}
}
public int CompareTo(TimerItem other)
{
if (ResultTime < other.ResultTime)
{
return -1;
}
if (ResultTime == other.ResultTime)
{
return 0;
}
else
return 1;
}
}
this is the class holding the linked list:
public static class TimersManager
{
private static LinkedList<TimerItem > TimerItems = new LinkedList<TimerItem>();
private static Timer _timer = new Timer();
public static void Add(TimerItem timerItem )
{
if (TimerItems.First == null || TimerItems.First.Value.CompareTo(timerItem ) > 0)
{
TimerItems.AddFirst(timerItem);
SetTimerToFirst();
}
else
{
var temp = TimerItems.First;
while (temp.Next != null && temp.Next.Value.CompareTo(timerItem) <= 0)
{
temp = temp.Next;
}
TimerItems.AddAfter(temp, timerItem);
}
}
private static void Completed(Object sender, EventArgs e)
{
_timer.Stop();
Console.WriteLine(TimerItems.First.Value.Id);
TimerItems.RemoveFirst();
if (TimerItems.First != null)
{
SetTimerToFirst();
}
}
private static void SetTimerToFirst()
{
_timer.Interval = TimerItems.First.Value.MilliSecondsCountToCompletion;
_timer.AutoReset = false;
_timer.Elapsed += Completed;
_timer.Start();
}
}