tags:

views:

58

answers:

1

Hello everyone,

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?

+1  A: 

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.

Jim Mischel
Thanks, I'll try that. It's very intermittent. The timer timeout is 1 minute - and maybe once per week it will simply stop. Problem is it's a level 2 notifiaction for us and it always happens when we're sound asleep!
Adam
The other strange part is that I have four other timers all setup in the exact same manner that do not have this issue - and I have several other windows services deployed using this same methodology. The methods you suggest have clear benefits, it's just odd that this specific instance is having an issue.
Adam