我有一个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处理完成”,然后随机定时器没有重启。
有什么想法吗?
答案 0 :(得分:2)
我认为这里存在潜在的重入问题,但我无法完全理解它。
我建议您在创建时将计时器的Timer.Stop
属性设置为Timer.Start
,而不是调用AutoReset
然后调用false
。这将防止任何重入问题,因为计时器在第一次间隔过去时自动停止。
除了删除调用iSMSPollTimer.Stop
的代码之外,您的处理程序代码保持不变。
我并不是说这肯定会解决你的问题,但它会消除对可重入问题的疑虑。
答案 1 :(得分:0)
这是在.NET服务中使用计时器的一个众所周知的问题。人们会告诉你使用不同类型的计时器(线程与系统),但最终他们也会失败。他们停止触发多长时间?间隔越短,失败的速度就越快。如果你把它设置为1秒,你会发现它每隔几个小时就会发生一次。
我发现为我工作的唯一解决方法是完全不依赖于计时器,而是使用带有Sleep函数的while循环。