C# 如何撞车以获得;“后续故障”;要考虑的Windows服务恢复问题

C# 如何撞车以获得;“后续故障”;要考虑的Windows服务恢复问题,c#,service,windows-services,C#,Service,Windows Services,我们有一个用C语言编写的Windows服务,它基本上在某个端口上启动一个Web API。服务配置为在第一次故障和第二次故障时重新启动。“后续故障”设置为“不采取行动”。 如果此端口可能被占用,服务将因未处理的异常而崩溃,并且在未处理的异常回调中,我们将转储文件写入特定的应用程序目录。无论出于何种原因,Windows不断地重新启动服务,即使它已经崩溃多次。我们的服务结构如下: public class WinService : ServiceBase { private WebApiHos

我们有一个用C语言编写的Windows服务,它基本上在某个端口上启动一个Web API。服务配置为在第一次故障和第二次故障时重新启动。“后续故障”设置为“不采取行动”。 如果此端口可能被占用,服务将因未处理的异常而崩溃,并且在未处理的异常回调中,我们将转储文件写入特定的应用程序目录。无论出于何种原因,Windows不断地重新启动服务,即使它已经崩溃多次。我们的服务结构如下:

public class WinService : ServiceBase
{
    private WebApiHostWrapper _apiHost;
    private Thread _workerThread;

    public WinService()
    {
        InitializeComponent();
        ServiceName = "MyService";
        // register handler for writing dumpfiles
        AppDomain.CurrentDomain.UnhandledException += UnhandledExceptions.DomainUnhandledException; 
    }

    protected override void OnStart(string[] args)
    {
        _workerThread = new Thread(InternalStart) { Name = "StartupThread" };
        _workerThread.Start(args);
    }

    private void InternalStart(object args)
    {
        if (null == _service)
        {
            Thread.MemoryBarrier();
            _apiHost= new WebApiHostWrapper();
            _apiHost.Start((string[])args); // exception here
        }
    }

    protected override void OnStop()
    {
        if (null != _workerThread)
        {
            _apiHost.Dispose();
            _apiHost= null;
            if (!_workerThread.Join(5000))
            {
                _workerThread.Abort();
            }
            Thread.MemoryBarrier();
            _workerThread = null;
        }
    }
在Windows事件日志中,我看到4个条目

  • 服务已成功启动。(来源:MyService)
  • 应用程序。。。。stacktrace等(来源:.NET运行时)
  • 错误的应用程序名称。。。dll和exe名称(来源:应用程序错误)
  • 故障存储桶,类型0。。。。(来源:Windows错误报告)

在端口已在使用的情况下,这会导致服务一次又一次地崩溃,系统中充斥着转储文件。Windows将始终独立于设置重新启动服务。是否有一种特殊的方法来崩溃,以便考虑“后续故障”,而不是重新启动服务

我发现了只导致执行“第一次失败”的问题。我们将“重置失败计数后”设置为0天。将此值设置为1后,服务崩溃2次,然后不再重新启动

资料来源:


不确定如何避免随后的重新启动tbh。我自己还没有做过这样的测试,但给你一个想法,在你的应用程序启动时,你可以尝试找到使用端口X的应用程序的pid,并可能会发送一个pid的终止标志?这样你的应用程序才能真正启动?保留端口只是应用程序启动过程中可能发生的许多事情之一。理论上,当我们在启动过程中检测到错误时,我们也可以完全停止,但这不是我们想要实现的。我们希望有转储文件来分析发生了什么,因为它可能是一个真正的错误,导致意外停止。