I have a TopShelf (3.1.3) service that hangs in a 'Stopping' state when an exception is raised. As a result none of the service recovery steps get invoked, and uninstalling the service only succeeds if the service is manually killed via 'taskkill'.
What is the recommended approach for handling exceptions in TopShelf? I do not wish to simply swallow/log the exception and continue. Ideally the call to hostControl.Stop would indeed put the service in a 'stopped' state, however this is not the case.
This thread asks a similar question, however it does not provide an answer: How to catch exception and stop Topshelf service?
Thoughts?
HostFactory.Run(o =>
{
o.UseNLog();
o.Service<TaskRunner>();
o.RunAsLocalSystem();
o.SetServiceName("MyService");
o.SetDisplayName("MyService");
o.SetDescription("MyService");
o.EnableServiceRecovery(r => r.RunProgram(1, "notepad.exe"));
});
public class TaskRunner : ServiceControl
{
private CancellationTokenSource cancellationTokenSource;
private Task mainTask;
public bool Start(HostControl hostControl)
{
var cancellationToken = cancellationTokenSource.Token;
this.mainTask = Task.Factory.StartNew(() =>
{
try
{
while (!this.cancellationTokenSource.IsCancellationRequested)
{
// ... service logic ...
throw new Exception("oops!");
}
}
catch (Exception)
{
hostControl.Stop();
}
});
return true;
}
public bool Stop(HostControl control)
{
this.cancellationTokenSource.Cancel();
this.mainTask.Wait();
return true;
}
}
It looks like topshelf catches exceptions and tries to close nicely, this means that that you can get circular logic with closing. Example, you have a thread which throws an exception, topshelf catches it and asks all stoppables to stop. One of these is the service that started the offending thread so it calls thread.join(); this means that it's waiting for itself to finish so it can finish. I think this is what happened with your task.wait().
So, solutions really boil down to:
I ended up with having timeouts which ends the service in a timely fashion and allows my exception logging to run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With