Reputation: 11
I have a windows service that runs four timers for a monitoring application. The timer in question opens a web request, polls a rest web service, and saves the results in a database.
Please see the elapsed method below:
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();
}
}
When I look at the log messages, I do get "iSMSPollTimer processing completed" and randomly afterwards the timer does not restart.
Any thoughts?
Upvotes: 1
Views: 812
Reputation: 4684
This is a pretty well known issue with using timers in .NET service. People will tell you to use a different type of timer (Threading vs System), but in the end they will also fail you. How long before they stop triggering? The shorter your interval, the faster it will fail. If you set it to 1 second, you'll see it happen every couple hours.
The only workaround that I found working for me, is not depending on timers altogether and use a while loop with a Sleep function inside.
Upvotes: 0
Reputation: 134045
I'm thinking there's a potential reentrancy problem here, but I can't put my finger on it exactly.
I would suggest that, rather than calling Timer.Stop
and then Timer.Start
, set the timer's AutoReset
property to false
when you create it. That will prevent any reentrancy problems because the timer is automatically stopped the first time the interval elapses.
Your handler code remains the same except that you remove the code that calls iSMSPollTimer.Stop
.
I'm not saying that this will solve your problem for sure, but it will remove the lingering doubt about a reentrancy problem.
Upvotes: 2