首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows服务System.Timers.Timer未启动

Windows服务System.Timers.Timer未启动
EN

Stack Overflow用户
提问于 2011-12-11 19:02:25
回答 6查看 39.3K关注 0票数 35

我有一个用C#编写的Windows服务,它意味着每隔几分钟执行一次任务。我使用的是一个System.Timers.Timer,但它似乎从未启动过。我在这里和其他地方看过许多不同的帖子,我不知道我的代码有什么问题。

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

代码语言:javascript
复制
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();
        }
    }
}

我真的为这件事绞尽脑汁。有人能发现我做错了什么蠢事吗?

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

我在服务中添加了文件跟踪日志,以确认一些内部内容,并且我确信,在完成Timer.Enabled ()时,OnStart值是真的。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-12-15 18:11:04

这是我的工作.

在花了很长时间寻找答案之后,我发现了很多文章和博客讨论Windows服务中的计时器。我看到了很多关于这方面的观点,它们都分为三类,并按频率的递减顺序排列:

  1. 不要使用System.Windows.Forms.Timer,因为它不能工作。(这才是有意义的)
  2. 不要使用System.Threading.Timer,因为它不起作用,而是使用System.Timers.Timer
  3. 不要使用System.Timers.Timer,因为它不起作用,而是使用System.Threading.Timer

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

我发现System.Timers.Timer只是在我的Windows应用程序中不起作用。因此,我转到了System.Threading.Timer。这令人讨厌,因为它需要进行一些重构才能正常工作。

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

代码语言:javascript
复制
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();
        }
    }
}

我讨厌“医生,医生,当我这么做的时候很疼.”解决办法,但这是我不得不求助的。再给下一个有这个问题的人一个意见.

票数 54
EN

Stack Overflow用户

发布于 2011-12-11 19:05:21

通过设置以下设置,您忘记了启用定时器

代码语言:javascript
复制
IntervalTimer.Enabled = true;

或者调用方法

代码语言:javascript
复制
IntervalTimer.Start();
代码语言:javascript
复制
protected override void OnStart(string[] args)
{
    // Set up the timer...
    IntervalTimer.Interval = Properties.Settings.Default.PollingFreqInSec * 1000;
    // Start the timer and wait for the next work to be released...
    IntervalTimer.Start();
}
票数 10
EN

Stack Overflow用户

发布于 2013-02-07 15:33:44

显然,System.Timers.Timer隐藏了任何例外,悄悄地吞没了它们,然后就窒息了。当然,您可以在作为处理程序添加到计时器中的方法中处理这些问题,但是如果在入口立即抛出异常(在执行第一行代码之前,如果您的方法声明了一个在强名称DLL中使用对象的变量(例如,该对象的版本是错误的),则永远不会看到该异常。

你要和我们一起扯掉你的头发。

或者你可以这么做:

  • 创建一个包装器方法,该方法(在try-catch循环中)调用您想要执行的方法。如果这个方法快死了,那么包装的方法可以执行异常处理,而不会杀死计时器,因为如果你不停止计时器,它就不会注意到出了什么问题。

(我确实停止了计时器,因为如果它失败了,再试一次对这个特定的应用程序来说是没有意义的。)

希望这能帮助那些从谷歌登陆的人(就像我一样)。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8466597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档