TopShelf service stuck in Stop state on exception

I have a TopShelf service (3.1.3) that hangs in the "Stopping" state when an exception occurs. As a result, none of the steps to restore the service is started, and the removal of the service is performed only if the service is manually killed using the "taskkill".

What is the recommended approach for handling exceptions in TopShelf? I do not want to just swallow / log the exception and continue. Ideally, calling hostControl.Stop would really put the service in a stopped state, but that is not the case.

This thread asks a similar question, but it does not give an answer: How to catch an exception and stop the 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;
    }
}
+4
2

, topshelf , , . , , , topshelf -. - , , thread.join(); , , , . , .wait().

, :

  • - /
  • , topshelf
  • topshelf

, , .

+1

while catch try

public bool Start(HostControl hostControl)
{
    var cancellationToken = cancellationTokenSource.Token;
    this.mainTask = Task.Factory.StartNew(() =>
        {
            while (!this.cancellationTokenSource.IsCancellationRequested)
            {                
                try
                {
                    // ... service logic ...
                    throw new Exception("oops!");
                }
                catch (Exception)
                {
                    hostControl.Stop();
                }
            }
        });
    return true;
}
0

All Articles