C# service, performs lots of things on start, windows doesnt give it enough time!

T

test

Hello all,

I am developing a windows service (c#, .net 2.0, windows 2003).

When the service starts it performs several functions that depend on
an internet connection, downloading rss feed etc.

The problem is, that if the connections is very slow, it takes a long
time for the status of the service to change from "starting" to
started, sometimes in fact, so long that windows gives up and says
that the service did not respond in a timely fashion.

If I wrap all my onstart functions into a timer.elapsed event instead,
the service status changes from starting to started instantly. I dont
like this though as it is not very eloquant. Is there a better way to
do this?

Many thanks,
Craig
 
B

Brian Gideon

Hello all,

I am developing a windows service (c#, .net 2.0, windows 2003).

When the service starts it performs several functions that depend on
an internet connection, downloading rss feed etc.

The problem is, that if the connections is very slow, it takes a long
time for the status of the service to change from "starting" to
started, sometimes in fact, so long that windows gives up and says
that the service did not respond in a timely fashion.

If I wrap all my onstart functions into a timer.elapsed event instead,
the service status changes from starting to started instantly. I dont
like this though as it is not very eloquant. Is there a better way to
do this?

Many thanks,
Craig

The OnStart method is suppose to do minimal work to get the service
initialized so that it can respond to the SCM quickly. Downloading
stuff from the internet sounds like something the service should be
doing as part of its main task and not as part of initialization.
 
J

Jack Jackson

Hello all,

I am developing a windows service (c#, .net 2.0, windows 2003).

When the service starts it performs several functions that depend on
an internet connection, downloading rss feed etc.

The problem is, that if the connections is very slow, it takes a long
time for the status of the service to change from "starting" to
started, sometimes in fact, so long that windows gives up and says
that the service did not respond in a timely fashion.

If I wrap all my onstart functions into a timer.elapsed event instead,
the service status changes from starting to started instantly. I dont
like this though as it is not very eloquant. Is there a better way to
do this?

Many thanks,
Craig

What do you do if there is no Internet connection when your service
starts?

It makes sense to me to separate the starting of the service from the
processing that occurs when an Internet connection becomes available
(which might or might not be when the service starts).
 
T

test

What do you do if there is no Internet connection when your service
starts?

It makes sense to me to separate the starting of the service from the
processing that occurs when an Internet connection becomes available
(which might or might not be when the service starts).

its in very early development right now (it's my first project, and
first attempt at learning a programming language).

Ok I have taken all the code out of the OnStart, replaced it with a
DoSomething(); function, and pasted the code into the DoSomething
function instead. It still takes ages to start up.

So what I have now done(lol) is this:

protected override void OnStart(string[] args)
{
ThreadStart starter = new ThreadStart(DoSomething);
Thread t = new Thread(starter);
t.Start();

}

Service now starts immediately. I have the feeling though that this is
cheating and not fixing an underlying problem.

With regard to the question about not having internet on start up, I
have yet to find a good way to test for internet connection, but if
the download fails, then it tries again 10 minutes later, using a
timer.

Thanks for such swift replies.
 
P

Peter Duniho

[...]
Ok I have taken all the code out of the OnStart, replaced it with a
DoSomething(); function, and pasted the code into the DoSomething
function instead. It still takes ages to start up.

What still takes ages to start up?

Does Windows still complain that your service is taking too long to
start and give up on you?

Or are you simply concerned that the service takes too long before it's
done the initialization it needs to do in order to be useful?

If the former, then you may need to post a concise-but-complete example
of code that reliably demonstrates the problem, since as near as I can
tell the code you posted shouldn't cause Windows to be concerned about
your start-up time.

If the latter, then that's an entirely different question. All that
moving the initialization out of OnStart() does is keep Windows from
thinking that your service has hung. But it won't change how long that
code takes to run; if the length of time it takes to run is also an
issue, you need to address that separately.

If the time-consuming aspect of your initialization involves
communicating over the Internet, then there may not be much you can do
about it. You should, of course, design the service so that its local
behavior is independent of the Internet-dependent aspects; it should
always be responsive locally, and provide a good way of reporting back
"I'm not ready yet" or some similar thing. But if you have to wait on
stuff on the other end of an Internet connection, you have to wait.

Pete
 
U

UL-Tomten

ThreadStart starter = new ThreadStart(DoSomething);
Thread t = new Thread(starter);
Service now starts immediately. I have the feeling though that this is
cheating and not fixing an underlying problem.

Maybe, maybe not. You could try looking at it from the point of view
of whoever is consuming the service. Is it important for the consumer
to know whether the service has finished the set-up work it does when
it starts? (For example, if the Windows Firewall Service is listed as
"Started", consumers would probably think it's safe to connect to the
Internet. Let's say the Firewall Service does what you do above, and
doesn't start censoring the Internet until DoSomething() is finished.
In this case, your approach is definitely cheating. But if requests to
and from the Internet will be pending in some sort of queue while the
Firewall service is DoingSomething, then it's still safe (but
certainly clumsy).)

As others have stated, a common compromise is to do only in OnStart()
what you need to tell the SCM whether you can actually start at all.
(For example, if the service really requires an Internet connection to
operate, then you might not want to tell the SCM you have started if
you cannot detect the presence of a suchly connection.)
 
T

test

Maybe, maybe not. You could try looking at it from the point of view
of whoever is consuming the service. Is it important for the consumer
to know whether the service has finished the set-up work it does when
it starts? (For example, if the Windows Firewall Service is listed as
"Started", consumers would probably think it's safe to connect to the
Internet. Let's say the Firewall Service does what you do above, and
doesn't start censoring the Internet until DoSomething() is finished.
In this case, your approach is definitely cheating. But if requests to
and from the Internet will be pending in some sort of queue while the
Firewall service is DoingSomething, then it's still safe (but
certainly clumsy).)

As others have stated, a common compromise is to do only in OnStart()
what you need to tell the SCM whether you can actually start at all.
(For example, if the service really requires an Internet connection to
operate, then you might not want to tell the SCM you have started if
you cannot detect the presence of a suchly connection.)

sorry guys, I was unclear. I am not concerned with the amount of time
my code takes to execute. I am not trying to speed that up.

I am trying to improve the speed of which the SCM shows the service as
"started" not "starting", because sometimes, the download of the RSS
items takes so long that the SCM gives up thinking the service has
hung.

Moving the code from onstart has fixed it, but I want to learn how I
can acheive the same thing better (ie, is there a way to tell SCM that
the service has started successfully etc etc)

Craig
 
J

Jani Järvinen [MVP]

Hi Craig,

you've got many other responses already, but I suggest that you take a look
at the ServiceBase class' method RequestAdditionalTime.

This method is:

"...intended to be called by the overridden OnContinue, OnPause, OnStart, or
OnStop methods to request additional time for a pending operation, to
prevent the Service Control Manager (SCM) from marking the service as not
responding. If the pending operation is not a continue, pause, start, or
stop, an InvalidOperationException is thrown".

This was from the MSDN documentation. This method might solve your issues,
if you call it in the OnStart event handler.

Hope this helps!

--
Regards,

Mr. Jani Järvinen
C# MVP
Helsinki, Finland
(e-mail address removed)
http://www.saunalahti.fi/janij/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top