如何为serviceStatus.dwWaitHint选择值?

Dan*_*Dan 5 c# windows-services quartz.net

我正在按照本教程进行操作:http : //msdn.microsoft.com/zh-cn/library/zt39148a( v= vs.110).aspx以创建Windows服务。我有一个名为的类TaskManager,它使用Quartz.Net管理大量工作。它具有.Go()(不阻塞)和.Stop()方法。如果我理解正确,那么我要做的就是

    private TaskManager _taskManager;

    public DataPumpService()
    {
        InitializeComponent();
        _taskManager = new TaskManager();
    }

    protected override void OnStart(string[] args)
    {
        _taskManager.Go();
    }

    protected override void OnStop()
    {
        _taskManager.Stop();
    }
Run Code Online (Sandbox Code Playgroud)

但是,本教程随后一节将介绍如何设置服务状态。它并没有真正解释什么是服务状态或何时要设置它。TaskManager.Stop()可能需要花费几秒钟才能完成(内部调用IScheduler.Interrupt()所有作业,然后调用IScheduler.Shutdown(true))。那我应该设置状态吗?如果是这样,那么假设我将代码包含在本教程的“设置服务状态”部分的(1),(2)和(3)部分中,那么执行以下操作是否正确(基本上对于上述第一个代码块中的这两种方法而言) :

    protected override void OnStop()
    {
        // Update the service state to Stop Pending.
        ServiceStatus serviceStatus = new ServiceStatus();
        serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING;
        serviceStatus.dwWaitHint = 100000;
        SetServiceStatus(this.ServiceHandle, ref serviceStatus);

        _taskManager.Stop();

        // Update the service state to Running.
        serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED;
        SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    }
Run Code Online (Sandbox Code Playgroud)

如果这是正确的,那么该serviceStatus.dwWaitHint = 100000;属性是我需要明智选择的东西,还是默认值是一件值得坚持的好事?基本上我不知道这个值是什么意思...

fro*_*ous 5

正如@HansPassant所说

ServiceBase 类已经处理服务状态的方式在 99.9% 的情况下已经足够好了。您不应该需要它,30 秒(默认值)足以启动/停止 99.9% 的所有服务。

但是如果你需要处理长时间的关闭,文档说关于

等待提示

挂起的开始、停止、暂停或继续操作所需的估计时间,以毫秒为单位。在指定的时间段过去之前,服务应该使用递增的 dwCheckPoint 值或 dwCurrentState 的更改对 SetServiceStatus 函数进行下一次调用。如果经过了 dwWaitHint 指定的时间量,并且 dwCheckPoint 没有增加或 dwCurrentState 没有改变,则服务控制管理器或服务控制程序可以假设发生了错误并且应该停止服务。但是,如果服务与其他服务共享一个进程,则服务控制管理器不能终止服务应用程序,因为它也必须终止共享该进程的其他服务。

数据检查点

服务定期递增的检查点值,以在冗长的启动、停止、暂停或继续操作期间报告其进度。例如,服务应在启动时完成其初始化的每个步骤时增加此值。调用对服务的操作的用户界面程序使用此值来跟踪冗长操作期间服务的进度。当服务没有启动、停止、暂停或继续操作挂起时,此值无效且应为零。

这就说明在脚注步行通过

服务控制管理器使用 SERVICE_STATUS 结构的 dwWaitHint 和 dwCheckpoint 成员来确定等待 Windows 服务启动或关闭的时间。如果您的 OnStart 和 OnStop 方法运行时间很长,您的服务可以通过使用递增的 dwCheckPoint 值再次调用 SetServiceStatus 来请求更多时间。

基于此,我编写了这样的停止代码。请注意,我运行了一些很长的任务并终止它们真的不是一个好主意,因此等待时间很长。

//set the status to pending close
var serviceStatus = new ServiceStatus
{
    dwCurrentState = ServiceState.SERVICE_STOP_PENDING,
    dwWaitHint = 120000//two minutes wait time
};
SetServiceStatus(this.ServiceHandle, ref serviceStatus);

Engine.Cancel();

while (Engine.IsRunning())
{
    System.Threading.Thread.Sleep(1000);
    serviceStatus.dwCheckPoint++;//updating the checkpoint so I don't get terminated
    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
Run Code Online (Sandbox Code Playgroud)