Windows服务中的计时器 - 没有真正起作用?

时间:2010-04-10 10:06:44

标签: windows-services timer timer-jobs

我在C#中有一个Windows NT服务,基本上每x秒唤醒一次,检查是否需要发送任何邮件通知,然后再回到睡眠状态。

它看起来像这样(Timer类来自System.Threading命名空间):

public partial class MyService : ServiceBase
{
    private Timer _timer;
    private int _timeIntervalBetweenRuns = 10000;

    public MyService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        // when NT Service starts - create timer to wake up every 10 seconds
        _timer = new Timer(OnTimer, null, _timeIntervalBetweenRuns, Timeout.Infinite);
    }

    protected override void OnStop()
    {
        // on stop - stop timer by freeing it
        _timer = null;
    }

    private void OnTimer(object state)
    {
        // when the timer fires, e.g. when 10 seconds are over 
        // stop the timer from firing again by freeing it
        _timer = null;

        // check for mail and sent out notifications, if required - works just fine
        MailHandler handler = new MailHandler();
        handler.CheckAndSendMail();

        // once done, re-enable the timer by creating it from scratch
        _timer = new Timer(OnTimer, null, _timeIntervalBetweenRuns, _timeIntervalBetweenRuns);
    }
}

发送邮件和所有工作都很好,服务也每隔10秒唤醒一次(实际上,这是一个来自配置文件的设置 - 本例简化)。

然而,有时,服务似乎太快醒了......

2010-04-09 22:50:16.390
2010-04-09 22:50:26.460
2010-04-09 22:50:36.483

2010-04-09 22:50:46.500
2010-04-09 22:50:46.537  ** why again after just 37 milliseconds...... ??

2010-04-09 22:50:56.507

工作正常到22:50:45.500 - 为什么它会在37毫秒之后记录另一个条目??

在这里,它看起来完全没有了......似乎每次10秒钟就会醒来两次甚至三次....

2010-04-09 22:51:16.527

2010-04-09 22:51:26.537
2010-04-09 22:51:26.537

2010-04-09 22:51:36.543
2010-04-09 22:51:36.543

2010-04-09 22:51:46.553
2010-04-09 22:51:46.553

2010-04-09 22:51:56.577
2010-04-09 22:51:56.577

2010-04-09 22:52:06.590
2010-04-09 22:52:06.590

2010-04-09 22:52:06.600
2010-04-09 22:52:06.600

任何想法为什么?这不是一个大问题,但我担心它可能会开始在服务器上施加太多负载,如果我配置的间隔(10秒,30秒 - 无论如何)似乎被越来越多地忽略,服务运行的时间越长

我错过了服务代码中非常基本的东西吗?我最终会有多个计时器,还是什么?我似乎无法弄清楚.....我选错了计时器(System.Threading.Timer)? .NET中至少有3个Timer类 - 为什么? :-)

3 个答案:

答案 0 :(得分:2)

实际上,问题似乎是我选择了错误的计时器类。

使用System.Threading.Timer,我在原始问题中解释了这些问题。

当我切换到System.Timers.Timer时,所有这些问题都消失了。

所以这仍然引出了一个问题:为什么.NET框架中至少有三个不同的Timer类,它们之间的(微妙)差异是什么?

答案 1 :(得分:1)

通过查看上面的代码并不明显,您将获得多个计时器。但在我看来,情况可能就是这样。因为System.Threading.Timer实现了IDisposable,所以不应该将变量归零,而应该调用dispose方法。

MSDN说...

  

当不再需要计时器时,请使用   Dispose方法释放   计时器持有的资源。

答案 2 :(得分:0)

这可能是因为消息管道。

有时会发送计时器消息,但处理速度不够快,因此它们会按顺序堆叠和处理。