Solved

Timer not working properly in windows service

Posted on 2008-11-02
4
1,986 Views
Last Modified: 2013-12-17
Hi Experts,

          I have written windows service interact with database. I have used two timers in that. first timer is used to read settings for the service for a xml file(sample is given) also checks if the system time is between starttime and end time of xml file then it enables the second timer else disable the second timer. The second timer is fired at time interval specified in xml file. method ProcessInvoiceBatch() is called by second timer.

code sample is attached.

My problem is that every thing works fine, but after some times the second timer stops working without any reason. means elapsed event of second timer stops firing. first timer is working properly because when i change the time interval for second timer in xml file second timer starts firing again. and again after some time ti stops.


I dont know what is causing this problem.

i m using Windows Server 2003 Sp2 machine.

Can anyone please help me overcoming this problem.

Regards,
Paramhans
// Windows service Code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Configuration;
using System.Timers;
using System.Data.SqlClient;
using System.Collections;
using System.IO;
using System.Xml;
 
namespace WinService_For_Processing_Invoice_Batch
{
    public partial class InvoiceBatchProcessingService : ServiceBase
    {
        Timer Tim = new Timer();
        Timer TimerUpdateSettings = new Timer();
        SqlConnection con;
        string StartTime, StopTime, ServiceName, TimeInterval, ServerName, DatabaseName, UserId, Password, LogFilePath;
 
        ConnectionClass cnCls;
        SqlCommand CmdInvoiceBatch, cmdBillingAwb, cmdSumAmt, CmdInvoiceHeader;
        string invoice_batch, branch_code, service, start_date, end_date, invoice_date, commercial_id;
        string StrQuery;
        SqlDataReader FetchInvoices, GetBillingData;
        SqlParameter param;
        localhost.LineHaul_Billing_Service ProcessInvoice = new localhost.LineHaul_Billing_Service();
 
        public InvoiceBatchProcessingService()
        {
            InitializeComponent();
 
            GetSettings();
 
            cnCls = new ConnectionClass(ServerName, DatabaseName, UserId, Password);
        }
 
        protected override void OnStart(string[] args)
        {
            Tim.Elapsed += new ElapsedEventHandler(Tim_Elapsed);
            TimerUpdateSettings.Elapsed += new ElapsedEventHandler(TimerUpdateSettings_Elapsed);
            addTOLog("Service Started................");
            
            TimerUpdateSettings.Interval = 60000;
            TimerUpdateSettings.Enabled = true;
 
            Tim.Enabled = true;
        }
 
        protected override void OnStop()
        {
            addTOLog("Service Stoped...............");
            Tim.Enabled = false;
            TimerUpdateSettings.Enabled = false;
        }
 
        void TimerUpdateSettings_Elapsed(object sender, ElapsedEventArgs e)
        {
            GetSettings();
            if ((DateTime.Now >= Convert.ToDateTime(StartTime)) && (DateTime.Now <= Convert.ToDateTime(StopTime)))
            {
                Tim.Enabled = true;
            }
            else
            {
                Tim.Enabled = false;
            }
        }
 
        protected void Tim_Elapsed(object source, ElapsedEventArgs e)
        {
            ProcessInvoiceBatch();
        }
 
        private void ProcessInvoiceBatch()
        {
           //my code;
        }
 
        public void addTOLog(string Message)
        {
            FileStream f = new FileStream(LogFilePath + "Logs_For_" + DateTime.Now.ToShortDateString().Replace('/', '_') + ".log", FileMode.Append);
            StreamWriter sw = new StreamWriter(f);
            sw.WriteLine("Log entry at " + DateTime.Now + ": " + Message);
            sw.Close();
            f.Close();
        }
 
        private void GetSettings()
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(@"path of my local drive\WinServiceSettings.xml");
            XmlNode node;
            node = xmlDoc.SelectSingleNode("//Setting[@ServiceName='InvoiceBatchProcessingService']");
 
            foreach (XmlAttribute a in node.Attributes)
            {
                switch (a.Name)
                {
                    case "StartTime":
                        StartTime = a.Value;
                        break;
                    case "StopTime":
                        StopTime = a.Value;
                        break;
                    case "ServiceName":
                        ServiceName = a.Value;
                        break;
                    case "TimeInterval":
                        TimeInterval = a.Value;
                        break;
                    case "ServerName":
                        ServerName = a.Value;
                        break;
                    case "DatabaseName":
                        DatabaseName = a.Value;
                        break;
                    case "UserId":
                        UserId = a.Value;
                        break;
                    case "Password":
                        Password = a.Value;
                        break;
                    case "LogFilePath":
                        LogFilePath = a.Value;
                        break;
                }
            }
 
            Tim.Interval = Convert.ToDouble(TimeInterval);
        }
    }
}
 
 
 
// Settings XML file.
 
<?xml version="1.0" encoding="utf-8" ?>
<Settings>
	<Setting 
		ServiceName="ServiceName" 
		StartTime="11:00" 
		StopTime="22:55"
		TimeInterval="60000"
		ServerName="MyServer"
		DatabaseName="MyDB"
		UserId=""
		Password=""
		LogFilePath="D:\Application_Data\Billing_Logs\WindowsService\Bill_Processing_Logs\" />
	
</Settings>

Open in new window

0
Comment
Question by:Paramhans
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 7

Assisted Solution

by:keustermans
keustermans earned 500 total points
ID: 22865842
Why use to timers. Sureley you can do everything in the first timer see code snippet.
you must also make sure that you stop the timer while processing end then enable it again when you are done.
Last thing I want to mention is that you could store the settings  that you read from your xml file in your app.config file.

void TimerUpdateSettings_Elapsed(object sender, ElapsedEventArgs e)
        {
            GetSettings();
            if ((DateTime.Now >= Convert.ToDateTime(StartTime)) && (DateTime.Now <= Convert.ToDateTime(StopTime)))
            {
                TimerUpdateSettings.Enabled = false;
                ProcessInvoiceBatch();
                TimerUpdateSettings.Enabled = true;
                
            }
                    }

Open in new window

0
 

Author Comment

by:Paramhans
ID: 22865965
Hi keustermans,

      First of all thanx for your reply.

       Now as per your suggestions goes:

       1) I need two timers first to get the settings at every min. or may be every sec. so that as soon as the xml file is updated it should get reflated in the service too. also my requirement was to fire the method "ProcessInvoiceBatch" every hour or at interval decided by the client. if i use only one timer both my requirements cant be fulfilled (as far as i can think). suppose client fixes time interval to 1 hour and starts the service and after some time he realizes he needs to set it to 30 mins. then the setting will change only after one hour. but in my case it will be affected only after 1 min and the method will be executed after 30 mins.

        2) Your second suggestion is good one and I'm surly gonna try this.

        3) As far as third on goes My client need a solution where he can store settings for more then one similar kind of win services at one location so that he dont hv to go to diffrent app.config files for changing the settings.



Thanx again for your reply.

Regards,
Paramhans
0
 
LVL 7

Accepted Solution

by:
keustermans earned 500 total points
ID: 22866097
You can still achieve this with one timer by writing a datetime stamp to registery as the last statement in ProcessInvoiceBatch().

You set your timer to read the xml file every minute to get the latest settings.

the first thing you do in ProcessInvoiceBatch() is to check if the required interval (retrieve from settings file) has passed, by deducting the time stored in the registery from the current time if the difference is equal or greater than settings interval execute the logic. The last thing that gets done in the function is to write a datetime stamp to the registry upon completion of the logic.

all you need to do is to write an inintial entry to the registery when you install your service so that there is time to compare to.
0
 

Author Comment

by:Paramhans
ID: 22866134
Thanx keustermans. I'll defiantly try it.
0

Featured Post

Stressed Out?

Watch some penguins on the livecam!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
In this post we will learn different types of Android Layout and some basics of an Android App.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question