Hi Mark,
Based on my understanding, you wanted to allow the service to leverage the
auto-restarting configuration while exceptions are generated in the
background worker thread. If I have misunderstood you, please feel free to
tell me, thanks.
Do you use .Net1.1 or .Net2.0 Windows Service? Do you catch the crash
exception in your thread proc? Based on my test in a VS2005 service with
auto-restarting configuration, if there is any unhandled exception
generated in the worker thread(without catching), the service process will
terminate and after 1 minite, the SCM will try to restart it again. My test
code is very simple, listed below:
private void ThreadProc()
{
throw new Exception("abc");
}
protected override void OnStart(string[] args)
{
System.Threading.Thread t = new System.Threading.Thread(new
System.Threading.ThreadStart(ThreadProc));
t.Start();
}
Based on my experience, the SCM will take action on the auto-restarting
feature if the service fails. A service fails if its process dies without
the service setting its state to SERVICE_STOPPED. This is the key point.
If the exception is not caught in the ThreadProc, it will certainly crash
the service process without setting status to SERVICE_STOPPED. So the
auto-restarting will take effect.
If you have caught the exception, the Stop() method will not take effect in
our scenario. This is because Stop() method internally calls DeferredStop()
method which uses SetServiceStatus with setting SERVICE_STOPPED(Note
SERVICE_STOPPED is of value 1 in const):
public void Stop()
{
this.DeferredStop();
}
private unsafe void DeferredStop()
{
fixed (NativeMethods.SERVICE_STATUS* service_statusRef1 =
&this.status)
{
int num1 = this.status.currentState;
this.status.checkPoint = 0;
this.status.waitHint = 0;
this.status.currentState = 3;
NativeMethods.SetServiceStatus(this.statusHandle,
service_statusRef1);
try
{
this.OnStop();
this.WriteEventLogEntry(Res.GetString("StopSuccess ful"));
this.status.currentState = 1;//This is SERVICE_STOPPED
NativeMethods.SetServiceStatus(this.statusHandle,
service_statusRef1);
....
}
catch (Exception exception2)
{
....
}
}
}
Also, the service main thread ServiceMainCallback will also call
SetServiceStatus with SERVICE_STOPPED. So if the main thread dies normally
or Stop() method is called, the service is recognized as exiting without
failure.
So, to achieve your requirement, we can not allow the main thread to exit
normally, one workaround is catching the exception in ThreadProc and does
the cleanup and save work in the catch handler. Finally, you may invoke
"throw;" keyword again to rethrow the exception. This will force the
service to die as failure, which allow the SCM to auto-restart the service
based on configuration.
Hope it helps.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.