Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Служба Windows отключается из-за простоя

Автор вопроса: CommunityОтветов: 2

Я создал службу Windows vb.net, которая ничего не делает, кроме как пингует веб-службу wcf и обрабатывает отправку запроса на обслуживание этой же веб-службы в ночное время. Он выполняет обе задачи, используя событие таймера. Если служба не делает ничего, кроме этих двух вещей, она говорит при запуске, что отключается из-за простоя. Потоку службы Windows нужно что-то сделать.

Каков наилучший способ предотвратить это отключение, не тратя впустую ресурсы машины? Или я пропустил какую-то настройку в API, чтобы отключить проверку простоя?

Protected Overrides Sub OnStart(ByVal args() As String)
    Dim keepAliveTimer As New System.Timers.Timer(3600000)
    AddHandler keepAliveTimer.Elapsed, AddressOf  IsWebserviceAliveHandler
    keepAliveTimer.AutoReset = True
    keepAliveTimer.Start()
    Dim interval As Integer = Me.CalculateInterval(8, 25)
    Dim timer As New System.Timers.Timer(interval)
    AddHandler timer.Elapsed, AddressOf SendDailyMaintenanceRequestHandler
    timer.AutoReset = True
    timer.Start()
End Sub
  • Как выглядит ваш метод OnStart()? Rowland Shaw 22.06.2009
  • Защищенные переопределения Sub OnStart(ByVal args() As String) Dim keepAliveTimer As New System.Timers.Timer(3600000) AddHandler keepAliveTimer.Elapsed, AddressOf IsWebserviceAliveHandler keepAliveTimer.AutoReset = True keepAliveTimer.Start() Dim interval As Integer = Me.CalculateInterval( 8, 25) Dim timer As New System.Timers.Timer(interval) AddHandler timer.Elapsed, AddressOf SendDailyMaintenanceRequestHandler timer.AutoReset = True timer.Start() End Sub 22.06.2009
  • Было бы интересно увидеть код в SendDailyMaintenanceRequestHandler (или хотя бы его структуру) Fredrik Mörk 22.06.2009
  • Может ли быть так, что объявление таймеров в OnStart приводит к тому, что они удаляются после завершения обработчика OnStart? Это означало бы: нет таймера, нечего делать, простоя, конец... Thorsten Dittmar 22.06.2009
  • @Торстен; таймер нельзя выбрасывать; подписка на событие создает ссылку, поэтому она остается активной, даже если переменная keepAliveTimer выходит за пределы области видимости. Fredrik Mörk 22.06.2009
  • СПАСИБО ВСЕМ, этот сайт самый лучший. Ответ Фредрика был исправлением ... Я хотел оценить его, но у меня нет репутации. Внешняя попытка перехвата является ДОЛЖНОЙ, чтобы убедиться, что вы действительно получаете сообщение об ошибке, когда что-то идет не так. Исключением было то, что CalculateInterval возвращает целое число, в то время как таймеру требуется двойной интервал. В любом случае, я не получил никаких сообщений об ошибках от службы Windows, только сообщение о тайм-ауте простоя. Спасибо вам всем... 23.06.2009

windows-services

Ответы

Ответ 1 · рейтинг 1 · Fredrik Mörk

Это должно хорошо работать, если таймер выполняет работу в сервисе. В прошлом году я реализовал своего рода "службу сердцебиения" для проекта. Вот (несколько урезанный) пример кода, как он выглядит:

// assumes that you have using System.Threading; in the top of the file
private Timer _heartbeatTimer;

protected override void OnStart(string[] args)
{
    // the GetTimerInterval function returns an int with the interval (picked
    // up from config file
    _heartbeatTimer = new Timer(HearbeatTimerHandler, null, new TimeSpan(0),
                                new TimeSpan(0, GetTimerInterval(), 0));
}


private static void HearbeatTimerHandler(object state)
{
    try
    {
        // do the work
    }
    catch (Exception ex)
    {
        // log the exception
    }
}

В нашем случае он регулярно отправляет запрос веб-серверу на запуск веб-приложения, если оно было остановлено (из-за перезапуска или чего-то подобного).

Ответ 2 · Thorsten Dittmar

В OnStart создайте новый поток, который зацикливается до тех пор, пока служба не будет остановлена. Он выполняет свою задачу, а затем ждет некоторое время. Таким образом, служба не остановится.

Следующее будет псевдокодом для метода потока:

while (!serviceStopped)
{
    try
    {
        PerformTask();
        Thread.Sleep(24 * 60 * 60000); // Wait 24 hours
    }
    catch (ThreadAbortException)
    {
       break;
    }
    catch
    {
       // Log errors
    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы