【问题标题】:Topshelf timeout issueTopshelf 超时问题
【发布时间】:2013-10-25 12:17:45
【问题描述】:

我们正在使用 Topshelf 来托管服务。在启动服务之前,我们正在调用数据库以加载大量数据。因此,在启动服务时,我们收到以下错误:

Start Service failed with return code '[7] ServiceRequestTimeout

我们正在使用以下代码来启动服务:

HostFactory.Run(x =>
            {
                x.Service<AppService>(s =>
                {
                    s.ConstructUsing(name => new AppService(s_resolver, baseAddress, resolver));
                    s.WhenStarted(svc => svc.Start());
                    s.WhenStopped(svc => svc.Stop());
                    s.WhenShutdown(svc => svc.Shutdown());
                });

                x.EnableShutdown();
                x.RunAsLocalService();
                x.StartAutomatically();
                x.SetDisplayName("Application Host");
                x.SetDescription("Application Host");
            });

如果我尝试使用 Visual Studio 启动服务,服务运行良好。但是当服务通过 Topshelf 托管时,我得到了超时错误。

我也尝试过使用hostControl.RequestAdditionalTime(TimeSpan.FromSeconds(300)) 但即使添加了额外的超时时间,我也无法解决问题。请提供您的建议。

【问题讨论】:

  • topshelf-4 为您提供 x.SetStartTimeOut(Timespan) 和 x.SetStopTimeout(TimeSpan)

标签: .net windows-services topshelf


【解决方案1】:

HostControl.RequestAdditionalTime 的文档没有说明的是,您最多只能要求 60 或 120 秒。否则它会忽略您的请求。

它在我所知道的任何地方都被完美地记录了:(如果你发现它记录在某个地方,请告诉我。

【讨论】:

  • 感谢特拉维斯的回复。我尝试将 120 设置为 AdditionalTime,但即使这样也不起作用。
  • 不。我会检查并让你知道 :) 但是我确定尝试了 120 并且没有成功
  • 您可以使用任务来获取数据库,然后继续实际 启动行为吗? Task.Run 花费的时间几乎为零...
  • @Travis:我对 Windows 服务了解不多……我只是想知道,为什么你说我们只能通过 60 或 120 秒?我快速查看了Source code,以验证这一点,但找不到任何东西......
  • @Hooman 这是底层 Windows 服务管理器(Windows,而不是 .NET API)的限制,我不清楚它是否仍然是对较新的服务器/桌面版本的限制,因为这是从 2013 年开始的我一直没有跟上。
【解决方案2】:

这里是龙

来自TopShelf

void HostControl.RequestAdditionalTime(TimeSpan timeRemaining)
    {
        _log.DebugFormat("Requesting additional time: {0}", timeRemaining);

        RequestAdditionalTime((int)timeRemaining.TotalMilliseconds);
    }

这里是来自 ServiceBase 的 JustDecompile

    /// <summary>Requests additional time for a pending operation.</summary>
    /// <param name="milliseconds">The requested time in milliseconds.</param>
    /// <exception cref="T:System.InvalidOperationException">The service is not in a pending state.</exception>
    [ComVisible(false)]
    public void RequestAdditionalTime(int milliseconds)
    {
        unsafe
        {
            fixed (NativeMethods.SERVICE_STATUS* sERVICESTATUSPointer = &this.status)
            {
                if (this.status.currentState != 5 && this.status.currentState != 2 && this.status.currentState != 3 && this.status.currentState != 6)
                {
                    throw new InvalidOperationException(Res.GetString("NotInPendingState"));
                }
                this.status.waitHint = milliseconds;
                this.status.checkPoint = this.status.checkPoint + 1;
                NativeMethods.SetServiceStatus(this.statusHandle, sERVICESTATUSPointer);
            }
        }
    }

【讨论】:

  • 我无法投票,因为我对 API 一无所知,但 LOL @“Here be Dragons”。
猜你喜欢
  • 2015-11-29
  • 2015-03-12
  • 1970-01-01
  • 2017-10-29
  • 2011-04-24
  • 2011-06-19
  • 2011-04-03
  • 2011-12-28
  • 2013-07-12
相关资源
最近更新 更多