带有计时器的.NET Windows服务停止响应

Bir*_*iri 18 c# windows-services timer

我有一个用c#编写的Windows服务.它内部有一个计时器,可以定期激活一些功能.所以我服务的骨架:

public partial class ArchiveService : ServiceBase
{
    Timer tickTack;
    int interval = 10;
    ...

    protected override void OnStart(string[] args)
    {
        tickTack = new Timer(1000 * interval);

        tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed);
        tickTack.Start();
    }

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

    private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

它工作了一段时间(如10-15天)然后停止.我的意思是服务显示为正在运行,但它没有做任何事情.我做了一些日志记录,问题可能是计时器,因为在间隔之后它不会调用tickTack_Elapsed函数.

我正在考虑在没有计时器的情况下使用无限循环重写它,这会在我设置的时间内停止处理.这也不是一个优雅的解决方案,我认为它可能会对内存产生一些副作用.

Timer是从System.Timers命名空间使用的,环境是Windows 2003.我在不同服务器上的两个不同服务中使用这种方法,但两者都产生了这种行为(这就是为什么我认为它以某种方式连接到我的代码或框架本身).

有人经历过这种行为吗?有什么不对?


编辑:

我编辑了这两项服务.一个人到处都有一个不错的尝试和更多的记录.第二个定期进行定时娱乐.他们都没有停止过,所以如果这种情况再持续一周,我会关闭这个问题.到目前为止,感谢大家.


编辑:

我关闭了这个问题因为什么都没发生 我的意思是我做了一些更改,但这些更改在这个问题上并不真正相关,而且从那时起这两个服务都没有任何问题.请将其标记为"已关闭且不再相关".

Ste*_*owe 18

吞噬了计时器中未处理的异常,他们默默地杀死计时器

将计时器代码的主体包装在try-catch块中

  • @spinon:我最讨厌的 .net 问题之一——这是自 .net 1.0 以来的一个设计缺陷,但即使在 12 年后它仍然没有修复! (2认同)

Sti*_*ack 5

我之前已经看过这个定时器和循环服务.通常情况是捕获的异常会停止计时器或循环线程,但不会在异常恢复过程中重新启动它.

对于你的其他点...我不认为有关于计时器的任何"优雅".对我来说,在代码中看到循环操作比定时器方法更直接.但优雅是主观的.

记忆问题?如果你写的不正确.如果Thread.Sleep()设置不正确,可能会造成处理器负担.


Nic*_*eon 3

正如许多受访者指出的那样,异常会被计时器吞噬。在我的 Windows 服务中,我使用 System.Threading.Timer。它有 Change(...) 方法,允许您启动/停止该计时器。可能出现异常的地方可能是重入问题 - 如果tickTack_Elapsed 执行时间长于计时器周期。通常我这样写定时器循环:

    void TimeLoop(object arg)
    {
        stopTimer();

        //Do some stuff

        startTimer();
    }
Run Code Online (Sandbox Code Playgroud)

您还可以lock(...)使用主循环来防止重入。