Reputation: 721
I have a Windows service which I put together from a number of blogs and forums, mainly questions I've asked and had answered here. The service works fine. The only problem is when I stop the service; pasted further down is what I see in the log files when I stop it.
public partial class GBBInvService : ServiceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(GBBInvService));
System.Timers.Timer timer = new System.Timers.Timer();
private volatile bool _requestStop=false;
private ManualResetEventSlim resetEvent = new ManualResetEventSlim(false);
public GBBInvService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_requestStop = false;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Interval = 18000;
timer.Enabled = true;
timer.Start();
log.Info("GBBInvService Service Started");
}
protected override void OnStop()
{
log.Info("inside stop");
if (!_requestStop)
{
log.Info("Stop not requested");
timer.Start();
}
else
{
log.Info("On Stop Called");
WaitUntilProcessCompleted();
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
log.Info("Timer elapsed at " + Convert.ToString(e.SignalTime));
InvProcessing();
}
private void InvProcessing()
{
try
{
resetEvent.Reset();
//*Processing here*
}
catch (Exception ex)
{
resetEvent.Set();
log.Error(ex.Message);
}
}
private void WaitUntilProcessCompleted()
{
resetEvent.Wait();
}
}
The service stops properly and starts again fine, but I don't know if my code is wrong because the log file is showing:
2013-04-23 14:53:01,062 [6] INFO GBBInvService.GBBInventoryService [(null)] – inside stop
2013-04-23 14:53:01,062 [6] INFO GBBInvService.GBBInventoryService [(null)] – Stop not requested
It's going inside of (!_requestStop)
instead of the else
. Is my code wrong? Would somebody be able to explain to me why it is going inside of (!_requestStop)
instead of the else statement.
Any advise would be greatly appreciated, as I've only just started getting a hands-on of Windows services and most recently logging.
Upvotes: 0
Views: 5608
Reputation: 8938
Based on the code you have shared, I think there are a few things going on:
_requestStop = true;
somewhere, !_requestStop
will always evaluate to true
. There is no possibility then that the else
in OnStop()
will execute. With volatile
added to _requestStop
's declaration, maybe you expected the OS to modify it, but the declaration should then be public
; and even then the OS is not going to automagically modify _requestStop
. So, yes, with respect to _requestStop
and expecting the else
to ever execute, your code seems wrong._requestStop
seems to betray mistrust that OnStop()
will only be called when it should be called (i.e. when a stop has been requested). Being new to Windows services, I guess I could see that, but such mistrust is unwarranted.Unless code you have not shared uses _requestStop
, here are the changes I would suggest for the specific issue and questions you raised about your code:
public partial class GBBInvService : ServiceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(GBBInvService));
System.Timers.Timer timer = new System.Timers.Timer();
//private volatile bool _requestStop=false; // no _requestStop
private ManualResetEventSlim resetEvent = new ManualResetEventSlim(false);
public GBBInvService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
//_requestStop = false;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Interval = 18000;
timer.Enabled = true;
timer.Start();
log.Info("GBBInvService Service Started");
}
protected override void OnStop()
{
//log.Info("inside stop");
//if (!_requestStop)
//{
// log.Info("Stop not requested");
// timer.Start();
//}
//else
//{
// log.Info("On Stop Called");
// WaitUntilProcessCompleted();
//}
WaitUntilProcessingCompleted();
log.Info("GBBInvService Service Stopped");
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
log.Info("Timer elapsed at " + Convert.ToString(e.SignalTime));
InvProcessing();
}
private void InvProcessing()
{
try
{
resetEvent.Reset();
//*Processing here*
}
catch (Exception ex)
{
log.Error(ex.Message);
}
finally
{
resetEvent.Set();
}
}
private void WaitUntilProcessCompleted()
{
resetEvent.Wait();
}
}
Upvotes: 2
Reputation: 949
Unless something changes _requestStop, it will always be false.
ServiceBase has no code that will automagically set _requestStop to true, and your program doesn't change it any where.
Your code is running as expected.
OnStop() is ran when a stop is REQUEST from the Windows Service Manager. See more at http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx
You would set
_requestStop = true
at the top of OnStop() to signal to the rest of the program to finish any tasks.
That said, I don't know what you want this program to do. I can advise further with more details as to what it's supposed to be doing.
Upvotes: 7
Reputation: 1063
i don't see what's wrong. your logic never change _requestStop = true. it's always false.
!false definitely will go through if-true block.
Upvotes: 1