我需要创建一个能够在其确定的时间内完成公告的线程,例如:
如果我应该在睡眠时使用线程计时器或线程以及如何计算何时应该运行每个公告,我会感到有点困惑。
要开始,我正在考虑一个类的列表来保存每个公告,类似于List<MyTimer>
,类如下:
public MyTimer
{
public string Announcement { get; set; }
public int Interval { get; set; } // if interval is 0 means
// it will run just once
public bool hasSpecificTime { get; set; } // if this is true then will run
// only once at the SpecificTime
public bool Done { get; set; }
public DateTime SpecificTime { get; set; }
}
使用后将删除特定时间公告。
至于线程,我正在考虑使用这样的东西:
Timer = new System.Threading.Timer(TimerCallback, null, 0, 1000);
private void TimerCallback(object state)
{
foreach (var item in timerList)
{
// not sure how to handle the intervals of each continuous announcement
// some code here for the the above
// Not sure if this would work either because of the milliseconds etc
// on the DateTime
if (item.hasSpecificTime && !item.Done && SpecificTime == DateTime.Now)
{
SendAnnouncement(item.Announcement);
item.Done = true;
}
}
}
我的实施是否符合我的要求?
我如何处理函数中的间隔和时间,正如我在问题中所说的那样我不确定如何计算它在正确的时间发送它?
答案 0 :(得分:1)
您需要更改
item.hasSpecificTime && !item.Done && SpecificTime == DateTime.Now
到
item.hasSpecificTime && !item.Done && SpecificTime <= DateTime.Now
否则你将几乎所有事件。
如果您的timerList
变大,则应将已完成的项目移至单独的列表,以避免始终循环完成大量已完成的项目。
修改强>
对于周期性事件,您还需要使用SpecificTime
增加Interval
。
您可以创建更精细的方案,但您的代码易于阅读和理解,这非常重要。
您可以使用的一种方案是将MyTimer
个实例存储在有序队列中,您首先保留最接近的SpecifiedTime
。然后,您可以将TimerCallback调度到队列中第一个元素的持续时间,而不是重复轮询完整列表。你还需要更多的簿记。如果您在队列中插入一个新项目并且该项恰好是下一个要执行的项目(在队列中排在第一位),则需要取消并重新启动计时器。
这更“优雅”,但只有当你有很多事件并且遇到性能问题(或1000毫秒分辨率不够精细)时才需要。
答案 1 :(得分:0)
只是一个建议:请不要生气。但在这种情况下,您应该尝试Rx operators,它比自定义计时器或线程实现更清晰,更易于维护。应尽可能地实现线程,因为管理和维护更复杂。