System.Timers.Timer / Threading.Timer vs Thread with While Loop + Thread.Sleep for Periodic Tasks

时间:2010-05-12 20:16:05

标签: c# multithreading timer

在我的应用程序中,我必须定期发送心跳到“兄弟”应用程序。

使用System.Timers.Timer / Threading.Timer或使用带有while循环和Thread.Sleep的线程更好吗?

心跳间隔为1秒。

while(!exit)
{
   //do work
   Thread.Sleep(1000);
}

myTimer.Start( () => { 
                       //do work 
                      }, 1000); //pseudo code (not actual syntax)...

4 个答案:

答案 0 :(得分:32)

System.Threading.Timer有我的投票。

System.Timers.Timer适用于基于服务器(您的代码在主机上作为服务器/服务运行而不是由用户运行)计时器功能。

一个带有While循环和Thread.Sleep命令的线程确实是一个糟糕的主意,因为.NET中存在更强大的Timer mecahnisms。

答案 1 :(得分:23)

Server Timers是与睡眠线程不同的生物。

首先,根据您的线程的优先级以及正在运行的其他内容,您的睡眠线程可能会或可能不会被唤醒并安排在您询问的时间间隔运行。如果间隔足够长,并且调度的精度并不重要,Thread.Sleep()是一个合理的选择。

另一方面,计时器可以在任何线程上提升事件,从而提供更好的调度功能。但是,使用定时器的成本在代码中会稍微复杂一些 - 而且您可能无法控制哪个线程运行定时器事件触发的逻辑。来自文档:

  

基于服务器的Timer专为   与工作线程一起使用   多线程环境。服务器   计时器可以在线程之间移动   处理凸起的Elapsed事件,   导致更准确   Windows计时器提升事件   时间。

另一个考虑因素是计时器在ThreadPool线程上调用他们的Elapsed委托。根据逻辑的耗时和/或复杂程度,您可能不希望在线程池上运行它 - 您可能需要专用线程。另一个带有定时器的因素是,如果处理时间足够长,则可能会在另一个线程上再次(并发)引发timer事件 - 如果正在运行的代码不是为了并发而构建的,则可能会出现问题。

请勿将服务器计时器与“ Windows Timers ”混淆。后者通常是指可以传递到窗口的WM_TIMER消息,允许应用程序在其主线程上安排和响应定时处理而不会休眠。但是,Windows计时器也可以引用Win API for low-level timing(与WM_TIMER不同)。

答案 2 :(得分:21)

都不是:)

睡觉通常是不受欢迎的(不幸的是我不记得细节,但对于一个,这是一个不间断的“阻止”),Timer带来了很多行李。如果可能的话,我会建议System.Threading.AutoResetEvent

// initially set to a "non-signaled" state, ie will block
// if inspected
private readonly AutoResetEvent _isStopping = new AutoResetEvent (false);

public void Process()
{
    TimeSpan waitInterval = TimeSpan.FromMilliseconds (1000);

    // will block for 'waitInterval', unless another thread,
    // say a thread requesting termination, wakes you up. if
    // no one signals you, WaitOne returns false, otherwise
    // if someone signals WaitOne returns true
    for (; !_isStopping.WaitOne (waitInterval); )
    {
        // do your thang!
    }
}

使用AutoResetEvent(或其表兄ManualResetEvent)保证带有线程安全信令的真正阻塞(对于诸如上面的优雅终止之类的事情)。最糟糕的是,它是Sleep

的更好替代品

希望这会有所帮助:)

答案 3 :(得分:1)

我发现实际扩展的唯一计时器实现是System.Threading.Timer。如果您正在处理非常重要数量的计划项目,那么所有其他实现似乎都是假的。