.NET计时器:在X秒内得到通知的最佳方法是什么?

时间:2020-03-06 14:52:23  来源:igfitidea点击:

假设我有一个非经常性事件,需要从现在开始X秒钟触发,例如超时。直观地讲,创建一个System.Timers.Timer并将其时间间隔设置为X * 1000,将其滴答声连接到事件并启动它是有意义的。由于这是非重复事件,因此我们只希望将其引发一次,然后在计时器滴答之后停止计时器。

但是,如果计时器确实是最好的方式,那么计时器固有地会重复发生,这使我不信任它。保存开始的时间,将计时器设置为每秒(甚至毫秒)计时,并在计时系统中轮询时间以仅在必要的时间过后才手动触发目标事件,这样会更好/更准确/更安全吗?

任何人都可以权衡哪种方法最好(也许还有我没想到的另一种选择)。如果我需要等待的时间以毫秒为单位,一种方法会变得比另一种方法更好吗?

解决方案

只需使用普通的计时器,并在其使用一次后将其禁用即可。
那应该可以解决问题。

system.threading.timer和system.timers.timer都支持此功能。

衍生出一个新的BackgroundWorker,睡眠,关闭。

var worker = new BackgroundWorker();
worker.DoWork += delegate {
  Thread.Sleep(30000); 
  DoStuff();
} 
worker.RunWorkerAsync();

只需将其设置为在X秒后打勾,然后在打勾的代码中执行以下操作:

timer.enabled = false;

为我工作。

System.Threading.Timer的此构造函数允许我们指定时间段。如果将此参数设置为-1,它将禁用定期信令,并且仅执行一次。

public Timer(
    TimerCallback callback,
    Object state,
    TimeSpan dueTime,
    TimeSpan period
)

如果我们想精确地测量时间,则应考虑将计时器频率加倍,并使用DateTime.Now与开始时间进行比较。计时器和Thread.Sleep的时间测量不一定精确。

我们可以使用AutoReset = true的System.Timers.Timer或者无限期(System.Threading.Timeout.Infinite = -1)的System.Threading.Timer来执行一次计时器。

无论哪种情况,如果没有重复间隔,都应在使用完计时器后将其处置(在Timers.Timer的事件处理程序中或者Threading.Timer的回调中)。