繁体   English   中英

TopShelf服务在异常时停留在“Stopping”状态

[英]TopShelf service stuck in 'Stopping' state on exception

我有一个TopShelf(3.1.3)服务,当引发异常时,它会挂起'Stopping'状态。 因此,不会调用任何服务恢复步骤,如果通过“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;
    }
}

它看起来像topshelf捕获异常并试图很好地关闭,这意味着你可以通过关闭获得循环逻辑。 例如,你有一个引发异常的线程,topshelf捕获它并要求所有stopables停止。 其中一个是启动违规线程的服务,因此它调用thread.join(); 这意味着它正在等待自己完成所以它可以完成。 我认为这是你的task.wait()发生的事情。

所以,解决方案真的归结为:

  • 等待/加入超时
  • 在他们到达topshelf之前自己处理异常
  • 不要使用topshelf

我最终得到了超时,以及时结束服务,并允许我的异常日志记录运行。

尝试在try catch块之外移动while循环

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM