2010-10-08 167 views
1

我有一个windows服务,为监视应用程序运行四个定时器。有问题的计时器打开一个Web请求,轮询一个其他Web服务,并将结果保存到数据库中。C#中的定时器windows服务不能重新启动

请参考下面的方法经过:

 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处理完毕”,并随机事后计时器没有重启。

有什么想法?

+0

这是在一个单一的线程? – 2010-10-08 15:59:14

+0

@Aaron:不太可能,因为服务中的定时器都使用多个线程来执行... – 2010-10-08 16:01:47

回答

2

我在想这里有一个潜在的重入问题,但我无法准确地把它放在手指上。

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

除非您删除调用iSMSPollTimer.Stop的代码,否则您的处理程序代码保持不变。

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

+0

谢谢,我会试试。这是非常间歇的。定时器超时是1分钟 - 也许每周一次它会停止。问题在于它对我们来说是一种二级通知,而且当我们睡得很熟时它总是会发生的! – Adam 2010-10-08 17:24:11

+0

另一个奇怪的部分是,我有四个其他计时器都以完全相同的方式安装,没有这个问题 - 而且我还使用相同的方法部署了其他几个Windows服务。你建议的方法有明显的好处,这个特定的实例有问题只是奇怪。 – Adam 2010-10-08 17:26:55

0

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

我发现为我工作的唯一解决方法是完全不依赖于定时器,并使用带有睡眠功能的while循环。