Windows 服务 System.Timers.Timer 未触发 [英] Windows Service System.Timers.Timer not firing

查看:35
本文介绍了Windows 服务 System.Timers.Timer 未触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 C# 编写的 Windows 服务,旨在每隔几分钟执行一次任务.我为此使用了 System.Timers.Timer 但它似乎从未触发过.我在 SO 和其他地方查看了许多不同的帖子,但我没有看到我的代码有什么问题.

I have a Windows service written in C# which is meant to perform a task every few minutes. I'm using a System.Timers.Timer for this but it doesn't ever appear to fire. I've looked at many different posts here on SO and elsewhere and I'm not seeing what is wrong with my code.

这是我的代码,为了清楚起见,删除了与计时器无关的项目...

Here is my code, with non-timer related items removed for clarity...

namespace NovaNotificationService
{
    public partial class NovaNotificationService : ServiceBase
    {
        private System.Timers.Timer IntervalTimer;
        public NovaNotificationService()
        {
            InitializeComponent();
            IntervalTimer = new System.Timers.Timer(60000);  // Default in case app.config is silent.
            IntervalTimer.Enabled = false;
            IntervalTimer.Elapsed += new ElapsedEventHandler(this.IntervalTimer_Elapsed);
        }

        protected override void OnStart(string[] args)
        {
            // Set up the timer...
            IntervalTimer.Enabled = false;
            IntervalTimer.Interval = Properties.Settings.Default.PollingFreqInSec * 1000;
            // Start the timer and wait for the next work to be released...
            IntervalTimer.Start();
        }

        protected override void OnStop()
        {
            IntervalTimer.Enabled = false;
        }

        private void IntervalTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {   // Do the thing that needs doing every few minutes...
            DoWork();
        }
    }
}

我真的为这个而挠头.有人能看出我做错了什么愚蠢的事情吗?

I'm really scratching my head over this one. Can anybody spot what silly thing I'm getting wrong?

根据建议,我在服务 OnStart 方法中的 IntervalTimer.Start(); 之前添加了 IntervalTimer.Enabled = true;.这不能解决问题.

By suggestion, I added IntervalTimer.Enabled = true; before IntervalTimer.Start(); in the service OnStart method. This doesn't resolve the issue.

我已将文件跟踪日志记录添加到服务中以确认一些内部结构,并且我确信在 OnStart() 完成时 Timer.Enabled 值为真.

I've added file trace logging into the service to confirm some of the internals and I know for sure that the Timer.Enabled value is true by the time OnStart() is finished.

推荐答案

这是我的解决方法...

在为此寻找答案花费了太多时间后,我发现了大量讨论 Windows 服务中的计时器的文章和博客.我已经看到了很多对此的意见,它们都分为三类,按频率降序排列:

After way too many hours searching for an answer to this, I discovered a wide variety of articles and blogs discussing timers in Windows services. I've seen a lot of opinions on this and they all fall into three categories and in descending order of frequency:

  1. 不要使用System.Windows.Forms.Timer,因为它不起作用.(这才有意义)

  1. Don't use System.Windows.Forms.Timer because it won't work. (this only makes sense)

不要使用 System.Threading.Timer 因为它不起作用,请改用 System.Timers.Timer.

Don't use System.Threading.Timer because it doesn't work, use System.Timers.Timer instead.

不要使用 System.Timers.Timer 因为它不起作用,请改用 System.Threading.Timer.

Don't use System.Timers.Timer because it doesn't work, use System.Threading.Timer instead.

基于此,我尝试了2.这也是微软似乎推荐的方法,因为他们说System.Timers.Timer适用于服务器应用程序".

Based on this, I tried 2. This is also the approach that seems to be recommended by Microsoft since they say that System.Timers.Timer is suited to "Server applications".

我发现 System.Timers.Timer 在我的 Windows 服务应用程序中不起作用.因此我已经切换到 System.Threading.Timer.这是一个麻烦,因为它需要一些重构才能使其工作.

What I've found is that System.Timers.Timer just doesn't work in my Windows Service application. Therefore I've switched over to System.Threading.Timer. It's a nuisance since it requires some refactoring to make it work.

这大概是我现在工作代码的样子...

This is approximately what my working code looks like now...

namespace NovaNotificationService
{
    public partial class NovaNotificationService : ServiceBase
    {
        private System.Threading.Timer IntervalTimer;
        public NovaNotificationService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            TimeSpan tsInterval = new TimeSpan(0, 0, Properties.Settings.Default.PollingFreqInSec);
            IntervalTimer = new System.Threading.Timer(
                new System.Threading.TimerCallback(IntervalTimer_Elapsed)
                , null, tsInterval, tsInterval);
        }

        protected override void OnStop()
        {
            IntervalTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            IntervalTimer.Dispose();
            IntervalTimer = null;
        }

        private void IntervalTimer_Elapsed(object state)
        {   // Do the thing that needs doing every few minutes...
            // (Omitted for simplicity is sentinel logic to prevent re-entering
            //  DoWork() if the previous "tick" has for some reason not completed.)
            DoWork();
        }
    }
}

我讨厌医生,医生,当我这样做时会很痛……"解决方案,但这就是我不得不诉诸的方法.对于下一个遇到这个问题的人来说,还有一个关于这个问题的意见......

I hate the "Doctor, doctor, it hurts when I do this..." solution, but that's what I had to resort to. One more opinion on the pile for the next guy with this problem...

这篇关于Windows 服务 System.Timers.Timer 未触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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