TopShelf服务在出现异常时处于“停止”状态

min*_*ods 5 c# error-handling windows-services topshelf

我有一个TopShelf(3.1.3)服务,当引发异常时,该服务会挂在“正在停止”状态。结果,没有任何服务恢复步骤被调用,并且只有通过“ taskkill”手动终止服务后,卸载服务才能成功。

在TopShelf中处理异常的推荐方法是什么?我不希望简单地吞下/记录异常并继续。理想情况下,对hostControl.Stop的调用确实会将服务置于“已停止”状态,但是事实并非如此。

该线程提出了类似的问题,但是它没有提供答案: 如何捕获异常并停止Topshelf服务?

有什么想法吗?

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 0

尝试将 while 循环移到 try catch 块之外

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;
}
Run Code Online (Sandbox Code Playgroud)