【问题标题】:Can a Windows Service take hours to shutdown gracefully?Windows 服务是否需要数小时才能正常关闭?
【发布时间】:2011-09-16 06:42:54
【问题描述】:

我们有一个 .NET Windows 服务,它以事务方式将大量高度关键的数据从 A 铲到 B。 我们还需要确保在服务中使用的所有外部组件都未正确分配,并且在关闭服务本身之前清理了所有内容。 这可能需要几个小时!原因是服务需要等待外部组件的回调,该回调会在 2、3 或 4 小时后到达。

  1. Windows 是否有可能等待这么长时间才能提供服务? 优雅地关机?
  2. 服务中是否有选项可以让我决定什么时候发生 该服务正在被操作系统关闭,例如避免 完全关闭?
  3. 另外,作为另一种情况,如果服务器需要 重启?服务可以等待几个小时吗?
  4. 操作系统在终止服务之前等待服务的时间是否有限制?

【问题讨论】:

  • 您忘记了:5. 在拔掉插头之前,一个人等待机器正常关闭的时间是否有限制?

标签: c# .net windows-services shutdown long-running-processes


【解决方案1】:

您可以使用CanStop, CanShutdown, CanHandlePowerEvent 在计算机关闭时收到通知并做出充分响应。

使用 ServiceBase.RequestAdditionalTime 方法请求额外的时间来终止您的线程:

protected override void OnShutdown() 
{
    base.RequestAdditionalTime(MaxTimeout);
    serviceCore.OnShutdown();
    Stop(); 
}

如果您的 OnShutdown() 阻塞超过 20 秒(默认值存储在注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout 中),您的服务将被标记为无响应并被终止。

There is a good blog post from the BCL team on that subject that I recommend.

【讨论】:

  • OnShutdown 内调用RequestAdditionalTime 将导致InvalidOperationException
【解决方案2】:

是的,服务可以在完成之前停止关闭,但应该这样做吗?注册表中有超时值,操作系统是什么?

我认为您需要将回调与其他组件分离,或者将数据缓冲到磁盘并以较小的片段发送。停电时会发生什么?或者,如果有人厌倦了等待并关机?

如果数据很重要,请在内存之外对其进行管理,并使进程可重新启动。这将解决您漫长的关机过程。同样,一种轮询组件以获取进度的方法,消除了对阻塞的依赖。

【讨论】:

  • 是的,数据在某种意义上是至关重要的。这是一个企业级应用程序,其中正在移动、解析和索引大量数据。问题是该组件工作缓慢。在任何给定时间,最多可能有 20,000 个回调等待发生,这也是它需要这么长时间的部分原因。轮询不是一种选择,因为它的 API 不允许我们这样做。
  • 搞砸了,每个电话肯定不会花几个小时吧?您可以使用较小的批次,并在多台机器上分配调用吗?
【解决方案3】:

您不能在 OnShutdown() 中使用 RequestAdditionalTime(MaxTimeout) ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 2020-03-14
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多