如何为 serviceStatus.dwWaitHint 选择值? [英] How to choose value for serviceStatus.dwWaitHint?

查看:70
本文介绍了如何为 serviceStatus.dwWaitHint 选择值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注本教程:http:///msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx 以创建 Windows 服务.我有一个名为 TaskManager 的类,它使用 Quartz.Net 来管理一堆作业.它有 .Go()(不会阻塞)和 .Stop() 方法.如果我理解正确的话,我在服务中需要做的就是

I am following this tutorial: http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx to create a windows service. I have a class called TaskManager which uses Quartz.Net to manage a bunch of jobs. It has .Go() (which doesn't block) and .Stop() methods. If I've understood correctly, all I need to do in my service is

    private TaskManager _taskManager;

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

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

    protected override void OnStop()
    {
        _taskManager.Stop();
    }

但是教程有一节是关于设置服务状态的.它并没有真正解释服务状态是什么或我想设置它的时间.TaskManager.Stop() 可能需要几秒钟才能完成(内部它在所有作业上调用 IScheduler.Interrupt(),然后 IScheduler.Shutdown(true)).那么我应该设置状态吗?如果是这样,那么假设我在 教程,执行以下操作是否正确(基本上对于我上面第一个代码块中的两种方法):

But then the tutorial has a section on setting the service status. It doesn't really explain what the service status is or when I would want to set it. TaskManager.Stop() can take a few seconds to finish (internally it call IScheduler.Interrupt() on all jobs and then IScheduler.Shutdown(true)). So should I be setting statuses? If so then assuming I include the code in sections (1), (2) and (3) from the Setting Service Status section of the tutorial, is it correct to do the following (essentially for both methods in my first code block above):

    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);
    }

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

If this is right, then is the serviceStatus.dwWaitHint = 100000; property something I need to choose wisely or is that default value a good thing to stick with? Essentially I have no idea what this value is for...

推荐答案

正如 @HansPassant 所说

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

The way the ServiceBase class already takes care of the service status is good enough in 99.9% of the cases. You should not need it, 30 seconds (the default) is good enough to get 99.9% of all services started/stopped.

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

But if you need to handle a long running close, the documentation says concerning

dwWaitHint

等待开始、停止、暂停或继续操作,以毫秒为单位.在指定之前时间已经过去,服务应该进行下一次调用带有递增 dwCheckPoint 的 SetServiceStatus 函数值或 dwCurrentState 的变化.如果指定的时间量通过 dwWaitHint 传递,并且 dwCheckPoint 没有增加或dwCurrentState 没有改变,服务控制管理器或服务控制程序可以假设发生了错误并且服务应该停止.但是,如果该服务与其他服务,服务控制管理器不能终止服务应用程序,因为它必须终止其他服务也分享过程.

The estimated time required for a pending start, stop, pause, or continue operation, in milliseconds. Before the specified amount of time has elapsed, the service should make its next call to the SetServiceStatus function with either an incremented dwCheckPoint value or a change in dwCurrentState. If the amount of time specified by dwWaitHint passes, and dwCheckPoint has not been incremented or dwCurrentState has not changed, the service control manager or service control program can assume that an error has occurred and the service should be stopped. However, if the service shares a process with other services, the service control manager cannot terminate the service application because it would have to terminate the other services sharing the process as well.

dwCheckPoint

服务定期增加的检查点值在漫长的开始、停止、暂停或继续操作.例如,服务应该增加这个当它完成初始化的每一步时的值启动.调用操作的用户界面程序服务使用此值来跟踪服务的进度在漫长的手术过程中.此值无效,应为零当服务没有开始、停止、暂停或继续时操作待处理.

The check-point value the service increments periodically to report its progress during a lengthy start, stop, pause, or continue operation. For example, the service should increment this value as it completes each step of its initialization when it is starting up. The user interface program that invoked the operation on the service uses this value to track the progress of the service during a lengthy operation. This value is not valid and should be zero when the service does not have a start, stop, pause, or continue operation pending.

这澄清了 walk- 中的脚注-通过.

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

The Service Control Manager uses the dwWaitHint and dwCheckpoint members of the SERVICE_STATUS structure to determine how much time to wait for a Windows Service to start or shut down. If your OnStart and OnStop methods run long, your service can request more time by calling SetServiceStatus again with an incremented dwCheckPoint value.

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

Based on that, I wrote my Stop code like such. Note that, I run some very long tasks and terminating them is really not a good idea hence the lengthy wait times.

//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);
}

这篇关于如何为 serviceStatus.dwWaitHint 选择值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆