如何为serviceStatus.dwWaitHint选择值?

时间:2014-10-07 17:04:59

标签: c# windows-services quartz.net

我正在遵循本教程:http://msdn.microsoft.com/en-us/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();
    }

但是教程中有一节介绍如何设置服务状态。它并没有真正解释服务状态是什么或何时我想设置它。 TaskManager.Stop()可能需要几秒钟才能完成(在内部调用所有作业IScheduler.Interrupt(),然后IScheduler.Shutdown(true))。我应该设置状态吗?如果是这样,那么假设我在the tutorial的设置服务状态部分中包含第(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);
    }

如果这是正确的,那么我需要明智地选择serviceStatus.dwWaitHint = 100000;属性,或者这个默认值是一个好事吗?基本上我不知道这个值是什么......

1 个答案:

答案 0 :(得分:2)

正如@HansPassant所说

  

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

但是如果你需要处理一个长时间的关闭,documentation说关于

  

dwWaitHint

     

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

  

dwCheckPoint

     

服务定期递增的检查点值   在漫长的开始,停止,暂停或   继续运作。例如,服务应该增加此值   值,因为它完成初始化的每一步   启动。调用操作的用户界面程序   该服务使用此值来跟踪服务的进度   在漫长的操作中。该值无效,应为零   当服务没有开始,停止,暂停或继续时   正在进行中

这澄清了walk-through中的脚注。

  

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

基于此,我写了这样的Stop代码。请注意,我运行一些非常长的任务并且终止它们实际上并不是一个好主意,因此漫长的等待时间。

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