RequestAdditionalTime()的安全开销是多少?

Lar*_*ann 10 c# windows-services

我有一个Windows服务,它在不同的线程上生成一组子活动,并且只有在所有这些活动都成功完成后才会终止.我不知道在收到停止信号后终止活动需要多长时间.在OnStop()期间,我等待该停止信号的间隔,并且只要系统愿意授予它就继续请求额外的时间.

这是基本结构:

class MyService : ServiceBase
{
    private CancellationTokenSource stopAllActivities;
    private CountdownEvent runningActivities;

    protected override void OnStart(string[] args)
    {
        // ... start a set of activities that signal runningActivities
        //       when they stop
        // ... initialize runningActivities to the number of activities
    }

    protected override void OnStop()
    {
        stopAllActivities.Cancel();

        while (!runningActivities.Wait(10000))
        {
            RequestAdditionalTime(15000); // NOTE: 5000 added for overhead
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该在RequestAdditionalTime通话中添加多少"开销" ?我担心请求是累积的,而不是基于每次RequestAdditionalTime调用的时间点.如果是这种情况,增加开销可能会导致系统最终拒绝该请求,因为将来它太过分了.但是如果我不添加任何开销,那么我的服务可以在它有机会请求下一个额外时间块之前终止.

Lar*_*ann 9

这篇文章并不完全令人鼓舞:

MSDN文档没有提到这一点,但似乎RequestAdditionalTime中指定的值实际上并不是"额外"时间.相反,它取代了ServicesPipeTimeout中的值.更糟糕的是,忽略任何超过两分钟(120000毫秒)的值,即上限为两分钟.

我希望情况并非如此,但我将此作为最坏情况的答案发布.

更新:该帖子的作者非常友好地发表了对我的评论的非常详细的答复,我在下面复制了这些评论.

拉尔斯,简短的回答是否定的.

我要说的是,我现在意识到Windows服务应该被设计为在需要时快速启动和终止处理.

作为开发人员,我们倾向于专注于处理的实现,然后将其打包并作为Windows服务提供.

但是,这确实不是设计Windows服务的正确方法.服务必须能够快速响应启动和停止请求,不仅是当管理员从服务控制台发出请求时,而且当操作系统在启动处理或停止时请求启动时,因为它正在关闭,

考虑当Windows配置为在UPS发出电源故障时关闭时会发生什么.这项服务不适合回应"我还需要几分钟......".

即使在执行长时间运行的处理任务时,也可以编写快速响应以停止请求的服务.通常,长时间运行的过程将包括批处理数据,并且处理应检查是否在确保数据一致性的最小工作单元级别请求停止.

例如,我发现停止超时的第一个服务是涉及处理远程服务器上的通知队列的问题.处理从队列中检索通知,调用Web服务以检索与通知主题相关的数据,然后编写数据文件以供另一个应用程序处理.

我将处理实现为对单个方法的计时器驱动调用.一旦调用该方法,它就不会返回,直到队列中的所有通知都被处理完毕.我意识到这是Windows服务的一个错误,因为偶尔队列中可能会有成千上万的通知,处理可能需要几分钟.

该方法能够每秒处理50个通知.所以,我应该做的是在处理每个通知之前执行检查以查看是否已请求停止.这将允许该方法在完成通知处理之后但在它开始处理下一个通知之前返回.这将确保服务快速响应停止请求,并且任何待处理的通知在服务重新启动时仍然排队等待处理.