Запланированное выполнение службы Windows - PullRequest
2 голосов
/ 09 июля 2009

Если у меня есть служба Windows, которая должна выполнять задачу каждые 30 секунд, что лучше использовать; класс Timer () или цикл, который выполняет задачу, затем спит несколько секунд?

class MessageReceiver 
{
    public MessageReceiver()
    {
    }

    public void CommencePolling()
    {
        while (true)
        {
            try 
            {
                this.ExecuteTask();     
                System.Threading.Thread.Sleep(30000);
            }
            catch (Exception)
            {
                // log the exception
            }
        }
    }

    public void ExecutedTask()
    {
        // do stuff
    }
}

class MessageReceiver 
{
    public MessageReceiver()
    {
    }

    public void CommencePolling()
    {
        var timer = new Timer()
            {
                AutoReset = true,
                Interval = 30000,
                Enabled = true
            };

        timer.Elapsed += Timer_Tick;    
    }

    public void Timer_Tick(object sender, ElapsedEventArgs args)
    {
        try 
        {
            // do stuff
        }
        catch (Exception)
        {
            // log the exception
        }
    }
}

Служба Windows создаст экземпляр класса MessageReciever и выполнит метод CommencePolling в новом потоке.

Ответы [ 5 ]

4 голосов
/ 09 июля 2009

Я думаю, это действительно зависит от вашего требования.

дело 1. Предположим, что вы хотите запускать this.ExecuteTask() каждые пять минут, начиная с 12:00 (т.е. 12:00, 12:05, ...), и предположим, что время выполнения this.ExecuteTask() варьируется (например, от 30 с до 2 min), возможно использование таймера вместо Thread.Sleep () кажется более простым способом сделать это (по крайней мере, для меня).

Однако вы можете добиться этого поведения также с помощью Thread.Sleep(), рассчитав смещение, принимая временные метки при пробуждении потока и при завершении this.ExecuteTask().

, дело 2. Предположим, что вы хотите выполнить задачу в следующие 5 минут сразу после завершения this.ExecuteTask(), использование Thread.Sleep() кажется более простым. Опять же, вы можете добиться этого поведения и с помощью таймера, сбрасывая таймер каждый раз, вычисляя смещения при каждом завершении this.ExecuteTask().

Примечание 1 , для случая 1 вы должны быть очень осторожны в следующем сценарии: что, если this.ExecuteTask() иногда занимает больше периода (т.е. начинается в 12:05 и заканчивается 12:13 в приведенном выше примере).

  1. Что это значит для вашего приложения и как оно будет обрабатываться?

    а. Полный сбой - отменить службу или отменить текущее (12:05) выполнение в 12:10 и запустить выполнение 12:10.
    б. Ничего страшного (пропустите 12:10 и запустите this.ExecuteTask() в 12:15).

    с. Ничего страшного, но нужно запускать выполнение в 12:10 сразу после завершения задачи в 12:05 (что, если это займет более 5 минут ??).

    * * +1034 д. Необходимо запустить выполнение 12:10, даже если выполнение 12:05 выполняется в данный момент.

    е. что-нибудь еще?

  2. Для политики, которую вы выбрали выше, легко ли ваш выбор реализации (таймер или Thread.Sleep()) поддерживать вашу политику?

Примечание2 . В .NET можно использовать несколько таймеров. Пожалуйста, ознакомьтесь со следующим документом (хотя он немного устарел, но кажется, что это хорошее начало): Сравнение классов таймеров в библиотеке классов .NET Framework

0 голосов
/ 09 июля 2009

Не ответил я, но Джон Сондерс (см. Выше) ... ответ можно найти здесь Для службы Windows, что лучше, ожидание или таймер?

0 голосов
/ 09 июля 2009

Я считаю, что оба метода эквивалентны. Поток будет в любом случае: либо потому, что вы его создаете, либо потому, что библиотека, реализующая класс Timer, создает его.

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

0 голосов
/ 09 июля 2009

Я это ответы на этот вопрос поможет.

0 голосов
/ 09 июля 2009

Вы делаете что-нибудь еще в течение этого десяти секундного ожидания? Использование Thread.sleep будет блокировать, мешая вам делать другие вещи. С точки зрения производительности, я не думаю, что вы увидите слишком много различий, но я бы сам не использовал Thread.sleep.

Существует три таймера на выбор - System.Windows.Forms.Timer реализован в основном потоке, тогда как System.Timers.Timer и System.Threading.Timer создают отдельные потоки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...