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);
}
}