我用 c# 编写了一个处理大量数据的 Windows 服务。当我们停止它尝试某个时间 20/30 秒然后抛出异常。
我想在 OnStop 事件中实现 ServiceBase.RequestAdditionalTime()。
我想知道 Windows 服务引发异常的确切超时时间,以便我可以在它之前请求额外的时间。
我搜索但没有找到这个默认的停止超时值。
我用 c# 编写了一个处理大量数据的 Windows 服务。当我们停止它尝试某个时间 20/30 秒然后抛出异常。
我想在 OnStop 事件中实现 ServiceBase.RequestAdditionalTime()。
我想知道 Windows 服务引发异常的确切超时时间,以便我可以在它之前请求额外的时间。
我搜索但没有找到这个默认的停止超时值。
我编写了以下代码来实现它。
protected override void OnStop()
{
int timeout = 10000;
var task = Task.Factory.StartNew(() => MyTask());
while (!task.Wait(timeout))
{
RequestAdditionalTime(timeout);
}
}
上面的代码启动了一个与主线程并行的任务(任务立即开始运行),下一行是每 10 秒检查一次任务是否完成,如果没有完成,它会请求额外的 10 秒并继续检查直到任务得到完全的。
尽管许多人提到了HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout
注册表项,但根据Microsoft 的这篇“服务控制处理程序”文章,该注册表项仅控制在 Windows 本身关闭或重新启动时服务可以关闭的最长时间:
<...> 为了防止服务停止关闭,服务控制器的等待时间是有限制的。如果通过服务管理单元关闭服务,则限制为 125 秒。如果操作系统正在重新启动,则时间限制在
WaitToKillServiceTimeout
值 <...>中指定
如果 Windows 未处于重新启动或关闭过程中,则 Windows 等待服务关闭的默认时间为 30 秒。但是,应用程序可以请求额外的时间,总共最多 125 秒(所有请求的总和)。
在 Windows Server 2003 及更高版本上,可以通过HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServicesPipeTimeout
注册表项更改此默认超时,如Microsoft 支持文章(和此 ServerFault 问题)中所述。目前尚不清楚这是否适用于 Windows 7/8/10,因为该文章仅提及服务器版本。
如果已在计算机上启动重新启动/关闭,则WaitToKillServiceTimeout
注册表项值(如果存在)指定 Windows 允许应用程序允许的最长时间,覆盖操作系统默认值。
据推测,这是为了使应用程序不能任意延迟关闭超出默认值(或管理员通过WaitToKillServiceTimeout
注册表项指定的值)。
它在子项的注册表中设置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
带字符串值WaitToKillServiceTimeout
。如果未定义,则默认为 20000 (ms)。在我的机器上,它似乎设置为 12000 (12s)。我从来没有碰过它。
默认情况下,我相信它是 12000 毫秒,要更改它,您需要访问注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout 并更改值
但是你可以定义你自己的超时时间如果你想启动它或停止它在这里编程你定义你自己的启动时间
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
在这里你定义你自己的停止时间
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
只需始终执行RequestAdditionalTime
, 您希望服务需要关闭的最长时间。早于预期完成并不是错误。