Windows service hanging

  • Thread starter Thread starter Ryan Breakspear
  • Start date Start date
R

Ryan Breakspear

Hi All,

I have a problem with a windows service. It seems to run happily for
sometimes hours, checking a database every second. It uses a timer and in
the _elapsed event, the timer is stopped, the processing is done, and the
timer is restarted. Errors are logged to the Event Log.

I don't know how or why the service stops working, but it still appears in
the processes list, but uses about half the amount of memory it was using
when it was working.

I have seen similar messages posted by people about C# services which stop
working but there doesn't seem to be an explanation. If you have any ideas
please let me know.

Below is the code from the _elapsed event of the timer (sorry about the bad
formatting)

Thanks in advance

Ryan

private void tmrService_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
// Stop the timer so this routine can't be called twice at the same time
tmrService.Stop();
CfdsServiceConnection ServiceConnection = null;
CfdsOptiTimeCOMManager OptiTime = null;
try
{
// Create database connection
ServiceConnection = new CfdsServiceConnection(FConnectionString);

// Do all processing here!!!!
OptiTime = new CfdsOptiTimeCOMManager(ServiceConnection.MainConnection,
elService);
OptiTime.ProcessNewReceived();
}
catch(Exception E)
{
// Add entry to Event log with error message
elService.WriteEntry(E.Message, EventLogEntryType.Error);
}
finally
{
// Make sure timer is started again or it'll never run!
tmrService.Start();

//Close connection if not null
if (ServiceConnection != null)
{
ServiceConnection.CloseConnection();
}
}
}
 
Two things that could possibly be help...

1) If your object is a com object try this code to decrement the com
counter before setting it to null.

if(myObj != null && Marshal.IsComObject(myObj))
{
while(Marshal.ReleaseComObject(mObj) > 0);
}
myObj = null;

2) In the timer, I used the enabled property with true/false rather
than the start/stop method.
 
Thanks for your message (and email), the objects I'm creating in the service
are all C# not COM (they are alll part of the same project).

I've just had a look at the decompiled code using a Reflection tool (by Lutz
Roeder which is excellent!), and the code for the Start method is:

public void Start()
{
this.Enabled = true;
}

So basically I'm still stuck! The problem seems to occur with other
services which have been written by my colleagues. They can execute
thousands of times, but something happens, and they still show in the
processes list, but use less memory, less threads and they don't seem to do
anything.

Thanks for you help, any other ideas, I'm tearing my hair out? Rather
predictably if left running in a debug mode it keeps working.

Ryan
 
Ryan Breakspear said:
Thanks for your message (and email), the objects I'm creating in the
service
are all C# not COM (they are alll part of the same project).

I've just had a look at the decompiled code using a Reflection tool (by
Lutz
Roeder which is excellent!), and the code for the Start method is:

public void Start()
{
this.Enabled = true;
}

So basically I'm still stuck! The problem seems to occur with other
services which have been written by my colleagues. They can execute
thousands of times, but something happens, and they still show in the
processes list, but use less memory, less threads and they don't seem to
do
anything.

Hmmm.. less threads, that should be an indication that your service
thread(s) died without your code catching an exception.
Note that exception don't flow between threads, so make sure your service
code is exception safe, and as a safety net, install an
UnhandledExceptionEventHandler.

Willy.
 
Hi,

Thanks for your message.

I don't create any threads in my code I've just overridden the OnStart() and
OnStop() methods of a System.ServiceProcess.ServiceBase, added a Timer to
it, then used the _Elapsed event to do my processing. I've tried adding
code that raises an exception in the Finally section of this event, and the
process carries on as usual, the service doesn't stop working.

In Delphi when writing a service you had to explicitely create a thread, I
presume this is all done for you in C#. Please correct me if I'm wrong, or
let me know if you have any other ideas.

Thanks

Ryan
 
Ryan Breakspear said:
Hi,

Thanks for your message.

I don't create any threads in my code I've just overridden the OnStart()
and
OnStop() methods of a System.ServiceProcess.ServiceBase, added a Timer to
it, then used the _Elapsed event to do my processing. I've tried adding
code that raises an exception in the Finally section of this event, and
the
process carries on as usual, the service doesn't stop working.

In Delphi when writing a service you had to explicitely create a thread, I
presume this is all done for you in C#. Please correct me if I'm wrong,
or
let me know if you have any other ideas.

Thanks

Ryan
No it's not done for you in C#, but your timer event handler(s) will run on
a threadpool thread.
It's difficult to tell what the problem is without seeing some code, but
following are some questions you could look at:
Can you tell us how many threads you have less when the service stops
working normally?
Can you also check the number of handles consumed by the service and see if
that number is not constantly increasing.
Are you sure the event service time is less than 1 sec., if not isn't there
a chance for deadlock, is your handler threadsafe?

Willy.
 
The code for my Timer_Elapsed event is in the first thread but it is
basically the following (psudocode):

Timer.Stop;
SQLConnection DBConnection;
try
DBConnection = new Connection();
DoProcessing;
catch
EventLog.WriteEntry("Oh I've errored");
finally
Timer.Start;
if (DBConnection != null)
DBConnection.Close;

I suppose a new thread could start while the old DBConnection was being
closed... that may cause the error. The service is being run every 100
milliseconds. I think the service was using 11 threads when it worked and 9
when it didn't. I'm not sure if all the code is threadsafe, I have some
file creation stuff, and I execute some queries. That's why I had the stop
timer at the start of the event, so it (hopefully wouldn't go in twice).

I there anyway I can have a critical section in the code, so it can never be
called twice at the same time? If not I could call a static procedure which
set a static variable (called Processing or something), and the routine
checked this variable?

Thanks again for your help

Ryan
 
Hi, just a quick update on what I've done.

The error was being caused because the timer was being executed twice. I
changed the AutoReset property to false.

I have also found a bug in the Timer (System.Timers.Timer), if you set the
Interval of a timer, it seems to execute it! This only seems to happen if
the timer has AutoReset set to true, and it has fired at least once. It's
as if the AutoReset property doesn't stop the timer properly.

Most odd

Ryan
 
There can be only one possiblity. There is an unhandled exception being
thrown. So, handle the exception or try to find out if there is an
exception at any instance of the Windows Service running.

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
Back
Top