Таймер в службе Windows - не работает? - PullRequest
1 голос
/ 10 апреля 2010

У меня есть служба Windows NT на C #, которая в основном просыпается каждые 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 ]

2 голосов
/ 16 апреля 2010

На самом деле проблема в том, что я выбрал неправильный класс таймера.

С System.Threading.Timer у меня есть те проблемы, которые я объяснил в своем первоначальном вопросе.

Когда я переключился на System.Timers.Timer, все эти проблемы исчезли.

Таким образом, все еще возникает вопрос: почему на платформе .NET есть как минимум три различных Timer класса, и в чем их (тонкие) различия?

1 голос
/ 12 апреля 2010

из приведенного выше кода не очевидно, что вы получаете несколько таймеров. но по моему это может быть так. потому что System.Threading.Timer реализует IDisposable, поэтому вместо обнуления переменной вы должны вместо этого вызвать метод dispose.

MSDN говорит ...

Когда таймер больше не нужен, используйте метод утилизации, чтобы освободить ресурсы, удерживаемые таймером.

0 голосов
/ 10 апреля 2010

Это, вероятно, потому что конвейер сообщений.

Иногда сообщения таймера отправляются, но обрабатываются недостаточно быстро, поэтому они укладываются и обрабатываются последовательно.

...