【问题标题】:Timer in C# windows service not restartingC# Windows 服务中的计时器未重新启动
【发布时间】:2012-07-16 22:04:30
【问题描述】:

我有一个为监视应用程序运行四个计时器的 Windows 服务。有问题的计时器打开一个 Web 请求,轮询一个 REST Web 服务,并将结果保存在数据库中。

请看下面经过的方法:

        void iSMSPollTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        iSMSPollTimer.Stop();
        try
        {
            Logger.Log("iSMSPollTimer elapsed - polling iSMS modem for new messages");
            string url = "http://...:../recvmsg?user=" + iSMSUser + "&passwd=" + iSMSPassword;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream resStream = response.GetResponseStream();

            XmlSerializer serializer = new XmlSerializer(typeof(Response));
            using (XmlReader reader = XmlReader.Create(resStream))
            {
                Response responseXml = (Response)serializer.Deserialize(reader);
                if (responseXml.MessageNotification != null)
                {
                    foreach (var messageWrapper in responseXml.MessageNotification)
                    {
                        DataContext dc = new DataContext();
                        DateTime monitorTimestamp = DateTime.Now;

                        if (messageWrapper.Message.ToUpper().EndsWith("..."))
                        {
                            //Saved to DB
                        }
                        else if (messageWrapper.Message.ToUpper().EndsWith("..."))
                        {
                            //Saved to DB
                        }
                        dc.SubmitChanges();
                    }
                }
                else
                {
                    Logger.Log("No messages waiting in the iSMS Modem");
                }
            }
            Logger.Log("iSMSPollTimer processing completed");
        }
        catch (Exception ex)
        {
            Logger.Log(GetExceptionLogMessage("iSMSPollTimer_Elapsed", ex));
            Logger.Debug(GetExceptionLogMessage("iSMSPollTimer_Elapsed", ex));
        }
        finally
        {
            iSMSPollTimer.Start();
        }
    }

当我查看日志消息时,我确实收到“iSMSPollTimer 处理完成”,然后随机计时器不会重新启动。

有什么想法吗?

【问题讨论】:

  • 这一切都在一个线程上?
  • @Aaron:不太可能,因为在服务中工作的计时器都使用多个线程来执行......

标签: c# service timer


【解决方案1】:

我认为这里存在潜在的重入问题,但我无法准确指出。

我建议不要先调用Timer.Stop,然后再调用Timer.Start,而是在创建计时器时将其AutoReset 属性设置为false。这将防止任何重入问题,因为计时器在第一次间隔结束时会自动停止。

您的处理程序代码保持不变,只是删除了调用iSMSPollTimer.Stop 的代码。

我并不是说这肯定会解决您的问题,但它会消除对重入问题的挥之不去的疑虑。

【讨论】:

  • 谢谢,我会试试的。这是非常断断续续的。计时器超时为 1 分钟 - 也许每周一次它会简单地停止。问题是它对我们来说是 2 级通知,而且它总是在我们熟睡时发生!
  • 另一个奇怪的部分是我有四个其他计时器都以完全相同的方式设置,没有这个问题 - 我有几个使用相同方法部署的其他 Windows 服务。您建议的方法有明显的好处,奇怪的是这个特定实例有问题。
【解决方案2】:

这是在 .NET 服务中使用计时器的一个众所周知的问题。人们会告诉你使用不同类型的计时器(线程与系统),但最终他们也会让你失望。他们多久停止触发?间隔越短,失败的速度就越快。如果您将其设置为 1 秒,您会看到它每隔几个小时发生一次。

我发现对我有用的唯一解决方法是完全不依赖计时器,而是使用内部带有睡眠功能的 while 循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多