Как использовать статический таймер в связанном списке? - PullRequest
0 голосов
/ 31 мая 2018

Я создаю связанный список объектов, содержащих время.связанный список отсортирован к тому времени, что означает, что самый ранний элемент будет первым.в классе, содержащем связанный список, у меня есть таймер, который должен работать всегда с первым элементом в списке.когда событие таймера выполнено, первый элемент удаляется, и таймер перезапускается с интервалом, установленным временем нового первого элемента.то же самое произошло, если был вставлен элемент с более ранним временем, чем первый элемент.ошибка: когда я запускаю программу с двумя элементами в списке, событие Elapsed происходит 3 раза, и поэтому я получаю ошибку this

System.NullReferenceException: 'Ссылка на объект не установлена ​​на экземпляробъект. '

System.Collections.Generic.LinkedList.First.get вернул null.

, поскольку первый элемент был удален и событие пытается напечатать его идентификатор.Мой вопрос заключается в том, почему третье событие произошло в первую очередь, так как таймер не должен активироваться, если в списке нет элементов.это класс элемента:

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

это класс, содержащий связанный список:

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();
    }
}

1 Ответ

0 голосов
/ 12 июня 2018

Простое добавление:

_timer.Elapsed -= Completed;

к методу Completed решило проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...