System.Threading.Timer ......下次火灾的时间?

时间:2015-06-19 11:45:31

标签: c# multithreading timer

我对计时器有疑问。间隔时间是否计算回调执行的时间?我的意思是例如 - 我有一个定时器设置为每15秒触发一次,它执行一个持续约3秒的回调函数。下次定时器何时开火?在18秒内(回调完成后)或15秒后(无需等待回拨)??? 提前致谢

2 个答案:

答案 0 :(得分:3)

无论回调执行时间如何,它都会每15秒触发一次。如果您希望它包含回调执行时间,您可以在回调中挂起并重新启动计时器,如下所示;

一开始:

someTimer.Change(Timeout.Infinite, Timeout.Infinite)

..最后,用同样的方法改回来:

someTimer.Change(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15))

答案 1 :(得分:0)

它将每15秒发射一次。回调的任何延迟都不会影响计时器。回调在单独的ThreadPool线程上执行。来自docs

  

该方法不会在创建计时器的线程上执行;它在系统提供的ThreadPool线程上执行。

如果您想考虑处理时间,您必须自己管理计时器 - 启动单火定时器并从回调内部重置它,例如:

TimerCallback tcb = MyCallBack;
//Start the timer once after 15 secs
_timer=new Timer(tcb,null,TimeSpan.FromSeconds(15),TimeSpan.Infinite);

...
void MyCallBack(Object stateInfo)
{
   ....
   //Reset the timer
   _timer.Change(TimeSpan.FromSeconds(15),TimeSpan.Infinite);
}

更简单,更简洁的方法是在每次异步执行后使用async/await等待X秒。例如,以下代码将在上次执行后15秒执行一个方法:

while(...)
{
    await Task.Delay(TimeSpan.FromSeconds(15));
    var response=await Task.Run(()=>someMethod());
    ...
}

或者,如果您想执行已经异步的代码

while(...)
{
    await Task.Delay(TimeSpan.FromSeconds(15));
    await myHttpClient.GetStringAsync(someURL);
}

在幕后,Task.Delay创建一个单火定时器,并在计时器完成时完成。这与你手动做的几乎相同。