c# - 如何在链表上使用静态计时器?
问题描述
我正在创建一个持有时间的对象的链接列表。链表按那个时间排序,这意味着最早的项目将是第一个。在持有链接列表的类中,我保留了一个计时器,该计时器应始终在列表中的第一项上运行。当计时器的事件完成时,第一项被删除,并且计时器以新的第一项的时间设置的间隔重新启动。如果插入时间早于第一个项目的项目,也会发生同样的情况。错误:当我使用列表中的 2 个项目运行程序时,Elapsed 事件发生 3 次,因此我收到此错误
System.NullReferenceException:“对象引用未设置为对象的实例。”
System.Collections.Generic.LinkedList.First.get 返回 null。
因为第一项已被删除,并且事件尝试打印它的 id。我的问题是为什么第三个事件首先发生,因为如果列表中没有项目,则不应激活计时器。这是项目类:
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();
}
}
解决方案
只需添加:
_timer.Elapsed -= Completed;
到 Completed 方法解决了问题
推荐阅读
- azure - 将 AKS 群集连接到托管虚拟机的虚拟网络
- r - 在 r 中合并两个 df 替换缺失值
- scrapy - 使用 Python 将图像类型的电子邮件转换为文本
- python - 创建条带订阅 Python
- python - 在不知道名称的情况下导入文件
- sql - Sqlite:多次更新(查找和替换)不区分大小写
- python - 使用 Tensorflow 后端时,如何打印 Keras 的 SGD 优化器变体的中间状态
- netsuite - 如何在保存记录上返回上下文类型?
- php - 允许我的用户使用带有 PHP 的 Google Calendar API 在我的日历中添加会议,而无需身份验证
- laravel - 如何为本文创建表格和设计关系