C#windows服务中的计时器无法重启

时间:2010-10-08 15:56:26

标签: c# service timer

我有一个Windows服务,为监控应用程序运行四个计时器。有问题的计时器打开Web请求,轮询其余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处理完成”,然后随机定时器没有重启。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我认为这里存在潜在的重入问题,但我无法完全理解它。

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

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

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

答案 1 :(得分:0)

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

我发现为我工作的唯一解决方法是完全不依赖于计时器,而是使用带有Sleep函数的while循环。