473,387 Members | 1,669 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Q: how to make service OnStop wait long enough?

This is my first attempt at writing a .NET service, and also my first
attempt at using threads. I don't know what I'm doing.

Below is some simplified code from my service class (inheriting from
ServiceBase). The OnStart calls a loop, which continues forever on its own
thread as long as _keepProcessing is true. This seems to work and I'm happy
with it.

However, OnStop is not working quite the way I would like. I would like
OnStop to set _keepProcessing to false, which should then cause the loop to
exit and that thread to terminate normally, thereby allowing OnStop to
finish normally as well. (Right?) But if _loopThread does not terminate
fast enough to suit OnStop (about a minute), a message pops up, "the service
didn't respond to the control request in a timely fashion" and then the
entire process is killed anyway. (!!!) This makes me uncomfortable.

Two questions:

1) Is my general approach below sensible, or is there a better way to
achieve the same basic effect?

2) Is there some way to make OnStop wait until the loop is really done
rather than just giving up waiting and killing the process?

Thanks for any advice,
Matt

-------------------------

private static bool _keepProcessing;
private static Thread _loopThread;

private static void AutomatedProcessingMain()
{
bool isTimeToDoStuff;

while(_keepProcessing)
{
try
{
if (isTimeToDoStuff == true) //setting iTTDS omitted here
DoStuff();
else
System.Threading.Thread.Sleep(15000);
}
catch (Exception x)
{
LogErrAndContinue(x);
}
}
}

static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;

ServicesToRun = new System.ServiceProcess.ServiceBase[] { new
AutoInterpreterService() };

System.ServiceProcess.ServiceBase.Run(ServicesToRu n);
}

protected override void OnStart(string[] args)
{
_keepProcessing = true;

_loopThread = new Thread(new ThreadStart(AutomatedProcessingMain));
_loopThread.IsBackground = true;
_loopThread.Start();
}

protected override void OnStop()
{
_keepProcessing = false;

while(_loopThread.IsAlive)
{
LogMessage("Waiting . . . " +
System.DateTime.Now.ToLongTimeString());
System.Threading.Thread.Sleep(10000);
}
}

Nov 16 '05 #1
3 11630
"Matt C." <ca*****@my-deja.com> wrote in message
news:Xn******************************@207.46.248.1 6...>
1) Is my general approach below sensible, or is there a better way to
achieve the same basic effect?
I would use a timer, then do your processing in the timer event handler. If
you would be accessing the timer from multiple threads then you would use
the System.Threading.Timer class, otherwise use the System.Timers.Timer
class. Note that the timer click runs on a threadpool thread, so it would
not necessarily be required to create a new thread yourself.

Pseudocode:

void OnStart() {
Timer.Interval = 15 seconds;
Timer.Start();
_Stop = false;
}

void OnStop() {
Timer.Stop();
_Stop = true;
}

void Timer_Click() {
Timer.Stop();

Do processing here.
You can check the value of _Stop at key places and
exit if this processing is time consuming.

if (!_Stop) Timer.Start(); // Do it this way in case OnStop has been
called while processing.
}
2) Is there some way to make OnStop wait until the loop is really done
rather than just giving up waiting and killing the process?


I don't think this is a problem with the way I showed you. It is not
necessary to wait for it to stop, since once the timer event handler exits
it will not be reentered again.

-- Alan
Nov 16 '05 #2
"Alan Pretre" <al********@newsgroup.nospam> wrote in
news:ej**************@tk2msftngp13.phx.gbl:
"Matt C." <ca*****@my-deja.com> wrote in message
news:Xn******************************@207.46.248.1 6...>
1) Is my general approach below sensible, or is there a better way to
achieve the same basic effect?
I would use a timer, then do your processing in the timer event
handler. If you would be accessing the timer from multiple threads
then you would use the System.Threading.Timer class, otherwise use the
System.Timers.Timer class. Note that the timer click runs on a
threadpool thread, so it would not necessarily be required to create a
new thread yourself.


Thanks for the response and the example.

OnStart, OnStop snipped.
void Timer_Click() {
Timer.Stop();

Do processing here.
You can check the value of _Stop at key places and
exit if this processing is time consuming.

if (!_Stop) Timer.Start(); // Do it this way in case OnStop has
been
called while processing.
}
2) Is there some way to make OnStop wait until the loop is really done
rather than just giving up waiting and killing the process?


I don't think this is a problem with the way I showed you. It is not
necessary to wait for it to stop, since once the timer event handler
exits it will not be reentered again.


However, if Timer_Click takes several minutes to complete, and OnStop is
called in the middle, it's going to kill Timer_Click() just the same way it
kills my AutomatedProcessingMain(), right?

What my application is doing is taking text files and processing them to a
database. A file might take several minutes to finish. I don't THINK a
forcible terminate in the middle of a file will cause any major problems,
only a leave little mess behind. I'd just rather avoid it if possible.

Peppering the file processing code with checks to _Stop is an idea, however
I am using that code in a desktop, non-service version of the app as well.
I think I'm not going to go there now, though I'll remember the suggestion.

I do think I will switch to the Timer idiom, probably easier for my
hypothetical successor to understand.

It occured to me that if there was just a way to abort OnStop entirely, I
could make that work. It sure does not look like it, though. If I could
set CanStop to false after the service was already running that would be an
acceptable workaround . . .

Anyway, thanks again for the suggestions.

Matt
Nov 16 '05 #3
Hi.

"Matt C." <ca*****@my-deja.com> wrote in message
news:Xn******************************@207.46.248.1 6...
However, if Timer_Click takes several minutes to complete, and OnStop is
called in the middle, it's going to kill Timer_Click() just the same way it kills my AutomatedProcessingMain(), right?
The last line of Timer_Click checks for the case where OnStop was called
during processing. It will not re-enable the timer when finished in that
case.
What my application is doing is taking text files and processing them to a
database. A file might take several minutes to finish. I don't THINK a
forcible terminate in the middle of a file will cause any major problems,
only a leave little mess behind. I'd just rather avoid it if possible.

Peppering the file processing code with checks to _Stop is an idea, however I am using that code in a desktop, non-service version of the app as well.
I think I'm not going to go there now, though I'll remember the suggestion.

Basically you have one thread (OnStop) that needs to communicate to another
thread (Timer) that it is time to stop. Since you say the processing task
can take several minutes to complete, what I would do is, create a database
transaction, then somewhere in your processing loop(s) (eg, reading the next
line from a file, or opening the next file, etc.) check the _Stop flag. If
that signals to stop, then rollback the database transaction and exit as
soon as you can. Using *one* strategic placement of the _Stop check in the
innermost loop nesting is probably sufficient to respond very nicely to the
OnStop command.
It occured to me that if there was just a way to abort OnStop entirely, I
could make that work. It sure does not look like it, though. If I could
set CanStop to false after the service was already running that would be an acceptable workaround . . .


I don't like that idea - the service should be under the control of people,
not the other way around. You want your service as responsive as possible
to the users.

-- Alan
Nov 16 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: ck388 | last post by:
I'm trying to perform a select query on an oracle database but I get this error. ORA-01840: input value not long enough for date format My query is: SELECT * FROM TIGER.VIEW_TNW_MAINSTREAM...
0
by: Blue Jean | last post by:
Hi, I have a column of datatype LONG and using the following jdbc code to insert the data: PreparedStatement ps = con.prepareStatement(command); byte in = str.getBytes();...
13
by: BK | last post by:
Can someone point me to a code sample that illustrates executing long running tasks (asynchronous) from a web application in ASP.NET? I assume that Web Services might come into play at some point,...
0
by: n_o_s_p_a__m | last post by:
OK, When I run my assembly in a regular windows application, all the threads terminate gracefully, using the recommended "graceful" synchronization mechanisms (autoresetevents, volatile statics,...
3
by: Bob Greschke | last post by:
I've resorted to actually drawing all of the characters of the alphabet on a graph to avoid having to drag around font files. It's mostly just uppercase characters, so it's not too bad. But I...
0
by: ArkJ | last post by:
Hello. I have a little problem. I created a little Service which uses SIP, all works rather well, but when I want to shut it down in the Services panel, it looks as if it's shut down, but in fact...
3
by: karthi84 | last post by:
Hi, I have created a windows service and i have written code in OnStart and OnStop event. when i manually start and stop the service it works fine. But when i restart the machine the OnStop event is...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.