windows System.Timers.Timer timer1_Elapsed 未触发!帮助!

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4628039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:55:52  来源:igfitidea点击:

System.Timers.Timer timer1_Elapsed not firing! Help!

c#windowsservice

提问by Bex

I am creating another windows service and my timer is not ticking and I have no idea why! I am using system.timers.timer as I have in previous services and it doesn't work. I have tried attaching to it but it doesn't seem to do anything.

我正在创建另一个 Windows 服务,但我的计时器没有计时,我不知道为什么!我正在使用 system.timers.timer ,因为我在以前的服务中使用过,但它不起作用。我试过附加到它,但它似乎没有做任何事情。

My code:

我的代码:

    namespace ExpiryNotifier
{
    public partial class ExpiryNotifier : ServiceBase
    {
        public ExpiryNotifier()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("ExpiryNotifier"))
            {
                System.Diagnostics.EventLog.CreateEventSource("ExpiryNotifier", "ExpiryNotifier");
            }
            eventLog1.Source = "ExpiryNotifier";
            eventLog1.Log = "ExpiryNotifier";
        }
        private Timer timer1 = new Timer();
        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("Service Started");
            timer1.Elapsed += timer1_Elapsed;
            timer1.Interval = 10000;
            timer1.Enabled = true;

        }

        protected override void OnStop()
        {
            eventLog1.WriteEntry("Service Stopped");
            timer1.Enabled = false;

        }

        private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            eventLog1.WriteEntry("timer tick");
            timer1.Stop();

            EmailerService.EmailerService service = new EmailerService.EmailerService();
            DataSet expiringQualifications = service.GetDetailsOfExpiringQualifications();

            if(expiringQualifications.Tables[0].Rows.Count>0)
            {
                foreach(DataRow rw in expiringQualifications.Tables[0].Rows)
                {
                    if (!string.IsNullOrEmpty(rw["EmailAddress"].ToString()) )
                    {
                        if (rw["QualAwardDescription"] != null)
                        {
                            service.SendQualExpiryEmail(rw["EmailAddress"].ToString(), rw["firstName"].ToString(),
                                                        rw["QualAwardDescription"].ToString());
                        }
                    }
                }
            }


            timer1.Start();
        }
    }
}

Can anyone see the problem?

任何人都可以看到问题吗?

Thanks in advance!

提前致谢!

Bex

贝克斯

回答by Hans Passant

System.Timers.Timer is an ugly timer. One nasty thing it does is swallow exceptions raised by the Elapsed event handler. Which will kill your timer since you stop it when entering the method. No notification whatsoever, it just stops working.

System.Timers.Timer 是一个丑陋的计时器。它所做的一件令人讨厌的事情是吞下由 Elapsed 事件处理程序引发的异常。这将杀死您的计时器,因为您在进入该方法时将其停止。没有任何通知,它只是停止工作。

You have to at least add exception handling to this code so you can log the exception and stop the service.

您必须至少向此代码添加异常处理,以便您可以记录异常并停止服务。

Also beware the bug in your OnStart() method, you'll keep adding an event handler each time the service gets started. The Elapsed event runs multiple times, in itself a good way to bomb something.

还要注意 OnStart() 方法中的错误,每次服务启动时,您将不断添加事件处理程序。Elapsed 事件运行多次,这本身就是一种轰炸某些东西的好方法。

Consider System.Threading.Timer, it doesn't have any of these problems.

考虑 System.Threading.Timer,它没有任何这些问题。

回答by HABJAN

System.Timers.Timer.Start() has a same function as System.Timers.Timer.Enabled=true; System.Timers.Timer.Stop() has a same function as System.Timers.Timer.Enabled=false;

System.Timers.Timer.Start() 与 System.Timers.Timer.Enabled=true 具有相同的功能;System.Timers.Timer.Stop() 与 System.Timers.Timer.Enabled=false 功能相同;

Those 2 methods internally sets Enabled property to true or false which starts or stops the timer.

这两种方法在内部将 Enabled 属性设置为 true 或 false 以启动或停止计时器。

Check if you have permission to write to eventlog. You can also check for errors in eventlog.

检查您是否有权写入事件日志。您还可以检查事件日志中的错误。

System.Timers.Timer is not thread safe. Make sure you use it properly.

System.Timers.Timer 不是线程安全的。确保正确使用它。

回答by JMorgan

I think timer1_Elapsedneeds to use the event delegate, so

我认为timer1_Elapsed需要使用事件委托,所以

timer1_Elapsed +=  new ElapsedEventHandler(timer1_Elapsed);

http://msdn.microsoft.com/es-es/library/system.timers.timer.aspx

http://msdn.microsoft.com/es-es/library/system.timers.timer.aspx

Though I would recommend the System.Threading.Timer for inside a service, as it will correctly throw exceptions inside the elapsed event. System.Timers.Timer just swallows them.

虽然我会推荐 System.Threading.Timer 用于服务内部,因为它会在经过的事件中正确抛出异常。System.Timers.Timer 只是吞噬了它们。

http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

回答by Conrad Frix

It looks like it works but you probably a better way to debug it. Who knows maybe your eventLog1is null

看起来它有效,但您可能是调试它的更好方法。谁知道也许你eventLog1是空的

Update your onstart to include this

更新您的 onstart 以包含此内容

 protected override void OnStart(string[] args)
     {
        foreach (string arg in args)
        {
            if (arg == "DEBUG_SERVICE")
                    DebugMode();

        }

     #if DEBUG
         DebugMode();
     #endif

     eventLog1.WriteEntry("Service Started");
     timer1.Elapsed += timer1_Elapsed;
     timer1.Interval = 10000;
     timer1.Enabled = true;

    }

private static void DebugMode()
{

    Debugger.Break();
}

Now when you hit start on the service you'll get a dialog asking if you want to attach. Its way easier then trying to attach manually.

现在,当您在服务上点击开始时,您会看到一个对话框,询问您是否要附加。它比尝试手动附加更容易。