views:

376

answers:

2

I've build a vb.net windows service which does nothing but ping a wcf webservice and handles sending a maintenance request to this same webservice at night time. It does both tasks using a timer event. If the service does nothing but these two things it says at startup that it's shutting down cause of being idle. The windows service thread needs something todo.

What is the best way to prevent this shutdown without wasting the machines resources? Or did I miss some setting on the api to disable the idle check?

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
A: 

In OnStart create a new thread that loops until the service is stopped. It performs its task and then waits for an amount of time. That way, the service won't stop.

The following would be pseudo-code for the thread method:

while (!serviceStopped)
{
    try
    {
        PerformTask();
        Thread.Sleep(24 * 60 * 60000); // Wait 24 hours
    }
    catch (ThreadAbortException)
    {
       break;
    }
    catch
    {
       // Log errors
    }
}
Thorsten Dittmar
I've tried this.. but my performtask is too quick.. It seems the service starter needs a busy thread for it to get into the fully started status. Sleeping at startup seems to also sleep the service startup. After a while it times out, so the service shows as not started, but the windows process itself did succeed to run.There must be a better solution.
Well, the thread IS busy - it is sleeping. To clarify: This is NOT the code for OnStart! In OnStart, you'd create a new thread with a thread method that contains the above code.
Thorsten Dittmar
A: 

It should work well having a timer performing work in a service. I have implemented a sort of "heartbeat service" for a project last year. Here is a (somewhat stripped down) code sample from how it looks:

// 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
    }
}

In our case it performs a request to a web server on a regular basis to have the web application start in case it was stopped (due to recycling or similar).

Fredrik Mörk
I did the exact same thing.. Started two timers like you did.. But in my case at startup of the service the starter pops a message something like "The service was shut down, in some cases this happens because it was idle"
Have you made sure to catch any exceptions that may occur?
Fredrik Mörk