gpt4 book ai didi

c# - Windows 服务无法停止

转载 作者:行者123 更新时间:2023-11-30 21:33:44 24 4
gpt4 key购买 nike

我有一个 Windows 服务的问题。有时服务无法停止并以运行状态挂起)在启动命令后显示以下消息:服务此时无法接受控制消息

简化的服务实现:

using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
public class Service : ServiceBase
{
protected object SyncRoot { get; } = new object();
protected override void OnStart(string[] args)
{
lock (SyncRoot)
{
var task = PerformHealthCheck();

while (!task.Wait(10000))
{
RequestAdditionalTime(10000);
}

Task.Factory.StartNew(() =>
{
//Some logic to start worker threads and initialize some startup processes
//All workers threads actually successfully executed.
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}

protected override void OnStop()
{
//Code is not reachable sometimes
lock (SyncRoot)
{
//Some stop logic
}
}

private static async Task PerformHealthCheck()
{
int status = 0;
do
{
status = CheckStatus();
if (status == 0)
{
await Task.Delay(20000);
}
}
while (status == 0);
}

private static int CheckStatus()
{
//Calculating HealthCheck status
return 0;
}
}
}

创建逻辑:

internal static class Program
{
private static void Main(string[] args)
{
ServiceBase.Run(new Service());
}
}

OnStart 方法成功执行到最后,OnStop 方法甚至没有命中。我可以在 WinDbg 中看到如下服务状态:

16 serviceType
4 currentState
5 controlsAccepted
0 win32ExitCode
0 serviceSpecificExitCode
0 checkPoint
0 waitHint

据我所知,服务显然处于运行状态并且已收到停止命令但没有执行它(我可以从日志中看到)。我不明白什么可能会阻止服务执行 OnStop 方法。 Windows事件 View 中可以看到启动命令,但没有停止命令。

其他信息:

  • .NET 4.5 框架
  • Windows 服务器 2012-2016

最佳答案

在您的示例中,PerformHealthCheck() 将无限期运行。因此,您的 OnStart 永远不会完成。不知道这是否只是因为您的简化示例。

但是,当事情发生时,您真的会记录下来吗?与此一样,记录 OnStart 方法的结尾并确认当问题发生时,OnStart 确实已完成。在你的代码注释中你写了 //Code is not reachable.. 你也在那里记录了一些东西吗?还是锁内?

顺便说一句,锁定启动和停止似乎是同步的好主意,但作为用户,如果我想停止服务,我真的很想停止它。不管它还处于启动状态。事实上,如果一个服务不响应停止命令,我怀疑 90% 的时间,任务管理器无论如何都是下一站......如果你尝试以这样的方式重写停止逻辑不是更好吗它总是会执行并中断它能做的一切吗?这可能会解决您的问题并改善我的体验。

编辑,看起来这些锁实际上并没有做任何事情(至少,如果它们只在这里使用而不是锁定其他地方)如果它仍然是 StartPending.. 操作系统将不会通过 OnStop 命令。 :

当启动只需要 LONG 并且在启动完成之前调用一次停止时,是否可能发生这种情况?看这个例子:

class logger
{
static readonly object _logSync = new object();

public void Log(string message)
{
var m = $"{DateTime.Now.ToString("HH:mm:ss")}; {message}{Environment.NewLine}";
lock(_logSync)
{
File.AppendAllText(@"C:\temp\test.txt", m);
}
}
}
class Program
{
static void Main(string[] args)
{
ServiceBase.Run(new TestHangService());
}
}
class TestHangService : ServiceBase
{
private logger _log;

public TestHangService()
{
_log = new logger();
}

protected override void OnStart(string[] args)
{
_log.Log("OnStart");
Thread.Sleep(30 * 1000);
_log.Log("OnStart exit");
}

protected override void OnStop()
{
_log.Log("OnStop");
}
}

然后

C:\WINDOWS\system32>sc create DeleteMe binpath="C:\testprojects\TestService\TestService\bin\Debug\TestService.exe"
[SC] CreateService SUCCESS

C:\WINDOWS\system32>sc start deleteMe

SERVICE_NAME: deleteMe
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 27376
FLAGS :

C:\WINDOWS\system32>echo "executed directly after starting"
"executed directly after starting"

C:\WINDOWS\system32>sc stop deleteMe

SERVICE_NAME: deleteMe
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

C:\WINDOWS\system32>echo "waiting for 30 sec"
"waiting for 30 sec"

C:\WINDOWS\system32>sc stop deleteMe
[SC] ControlService FAILED 1061:

The service cannot accept control messages at this time.

哪些日志:

18:32:20;启动

18:32:50; OnStart 退出

注意不是onstop

即使在 10 分钟后,它似乎也不会从中恢复(顺便说一句,这让我感到惊讶):

C:\WINDOWS\system32>sc query deleteme

SERVICE_NAME: deleteme
TYPE : 10 WIN32_OWN_PROCESS
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

C:\WINDOWS\system32>sc stop deleteme
[SC] ControlService FAILED 1061:

The service cannot accept control messages at this time.

关于c# - Windows 服务无法停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51085640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com