Как создать эффективный цикл для выполнения действий каждые X минут в службах Windows? - PullRequest
1 голос
/ 25 июля 2010

Я пишу службу Windows, которая должна выполнять действие каждые, скажем, 60 секунд.

Как лучше всего реализовать этот основной цикл?

Реализации, которые я имеюдо сих пор:
1) Использование объекта Timer, который выполняет делегат каждые xx секунд
2) Использование ManualResetEvents (реализация, которую я видел, выполняется только один раз,но, насколько я понял, можно создать цикл с такими повторными событиями)

Служба Windows будет работать постоянно, поэтому было бы лучше создать службу без утечки памяти.

Каков наилучший способ реализовать этот основной цикл?

Редактировать после комментариев: Действие, которое будет выполняться каждые X секунд, запустит несколько (скажем, максимум 10) потоков,Каждый поток не работает дольше 30 секунд

Ответы [ 5 ]

3 голосов
/ 25 июля 2010

Рассмотрите возможность использования Quartz.net .Я использую эту библиотеку, и я очень доволен ею.Вы можете установить расписание cron, которое будет соответствовать вашим потребностям.

3 голосов
/ 25 июля 2010

Используйте таймер.Это сделает намерение программы наиболее ясным.Таймер легко запустить и остановить с помощью методов OnStart и OnStop, и обратные вызовы сработают в пуле потоков, чтобы вы не связали поток.Объект Timer не утечет память сам по себе.(Вы все еще можете написать ошибку, которая приводит к утечке памяти, но это одинаково легко сделать с любой реализацией основного цикла.)

2 голосов
/ 25 июля 2010

Если вы используете system.timers.timer, убедитесь, что для автоматического сброса задано значение false, запустите его и завершите процесс. Вот полный пример

Требуется: служба Windows, выполняющая задания из очереди заданий в БД; Требуется: Пример кода

1 голос
/ 26 июля 2010

Вот еще один довольно распространенный паттерн, использующий ManualResetEvent как механизм остановки и регулирования.

public class Example
{
  private Thread m_Thread;
  private ManualResetEvent m_StopSignal = new ManualResetEvent(false);

  public void Start()
  {
    m_Thread = new Thread(Run);
    m_Thread.Start();
  }

  public void Stop()
  {
    m_StopSignal.Set();
    if (!m_Thread.Join(MAX_WAIT_TIME))
    {
      m_Thread.Abort() // Abort as a last resort.
    }
  }

  private void Run()
  {
    while (!m_StopSignal.WaitOne(YOUR_INTERVAL))
    {
      // Your task goes here.
    }
  }
}
1 голос
/ 25 июля 2010

Если нет никаких шансов, что ваше действие не займет больше времени, чем хх секунд, я бы просто использовал таймер.Если нет, я бы пошел с ManualResetEvents.Я предполагаю, что вы не хотите, чтобы одновременно выполнялось более одного действия.

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