Devasish
Devasish

Reputation: 41

System.Timers not working properly

hi i am writing a windows and wpf services for sending email automatically every day in same time 9:00. The web services is working properly, windows services also work fine in my local system every day. in server system it was not working in proper time..

protected override void OnStart(string[] args)
{
    this.WriteToFile("Simple Service started {0}");
    this.ScheduleService();
}

protected override void OnStop()
{
    this.ServicesStop();
    this.WriteToFile("Simple Service stopped {0}");
    this.Schedular.Dispose();
}

private Timer Schedular;

public void ScheduleService()
{
    try
    {
        //Set the Default Time.
        //DateTime scheduledTime = DateTime.MinValue;
        //Get the Scheduled Time from AppSettings.
        DateTime scheduledTime = DateTime.Parse(System.Configuration.ConfigurationManager.AppSettings["ScheduledTime"]);
        WriteToFile("Service entered " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));

        TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
        if ((timeSpan.Days < 0 || timeSpan.Hours < 0 || timeSpan.Minutes < 0 || timeSpan.Seconds < 0))
        {
            scheduledTime = scheduledTime.AddDays(1);
            timeSpan = scheduledTime.Subtract(DateTime.Now);
        }

        string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

        this.WriteToFile("Simple Service scheduled to run after: " + schedule + " {0}");

        //Get the difference in Minutes between the Scheduled and Current Time.
        Int64 dueTime = Convert.ToInt64(timeSpan.TotalMilliseconds);
        this.WriteToFile("dueTime to be fired: " + dueTime + " {0}");
        //Change the Timer's Due Time.
        Schedular = new Timer(dueTime);
        Schedular.Elapsed += new ElapsedEventHandler(Elpaesdtime);
        Schedular.Enabled = true;
    }
    catch (Exception ex)
    {
        WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

        //Stop the Windows Service.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
        {
            serviceController.Stop();
        }
    }
}

private void Elapsedtime(object sender, System.Timers.ElapsedEventArgs e)
{
    DateTime scheduledTime = DateTime.Parse(System.Configuration.ConfigurationManager.AppSettings["ScheduledTime"]);
    WriteToFile("Service entered " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));
    if (DateTime.Now.ToString("MM/dd/yyyy_hh_mm") == scheduledTime.ToString("MM/dd/yyyy_hh_mm"))
    {
        WriteToFile("Service executed " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));
        SystemReportServices.ReportServiceClient service = new SystemReportServices.ReportServiceClient();
        service.sendEmailToAdmin();
        service.sendEmailToUser();
        //ExportExcelastDay();
        //If Scheduled Time is passed set Schedule for the next day.
        scheduledTime = scheduledTime.AddDays(1);
    }

    //WriteToFile("Service executed " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));

    TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
    if ((timeSpan.Days < 0 || timeSpan.Hours < 0 || timeSpan.Minutes < 0 || timeSpan.Seconds < 0))
    {
        scheduledTime = scheduledTime.AddDays(1);
        timeSpan = scheduledTime.Subtract(DateTime.Now);
    }
    string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

    this.WriteToFile("Simple Service scheduled to run after: " + schedule + " {0}");

    //Get the difference in Minutes between the Scheduled and Current Time.
    Int64 dueTime = Convert.ToInt64(timeSpan.TotalMilliseconds);
    this.WriteToFile("dueTime to be fired: " + dueTime + " {0}");
    //Change the Timer's Due Time.
    Schedular.Dispose();
    Schedular = new Timer(dueTime);
    Schedular.Elapsed += new ElapsedEventHandler(Elpaesdtime);
    Schedular.Enabled = true;
}

private void SchedularCallback(object e)
{
    this.WriteToFile("Simple Service Log: {0}");
    this.ScheduleService();
}

private void WriteToFile(string text)
{
    string path = @"D:\\SystemReportServicesLog\WindowsServiceLog.txt";
    using (StreamWriter writer = new StreamWriter(path, true))
    {
        writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
        writer.Close();
    }
}

Upvotes: 0

Views: 173

Answers (2)

Sharkz
Sharkz

Reputation: 458

In my experience timers have always given a hard time getting them right, so instead I use a quartz library which handles scheduling very well.

Sample code from their documentation, you can setup the trigger to meet your needs. There are more kinds of triggers that you may want to look into.


using System;
using System.Threading;

using Quartz;
using Quartz.Impl;
using Quartz.Job;

namespace ConsoleApplication1
{
    public class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter {Level = Common.Logging.LogLevel.Info};

                // Grab the Scheduler instance from the Factory 
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();

                // and start it off
                scheduler.Start();

                // define the job and tie it to our HelloJob class
                IJobDetail job = JobBuilder.Create<HelloJob>()
                    .WithIdentity("job1", "group1")
                    .Build();

                // Trigger the job to run now, and then repeat every 10 seconds
                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity("trigger1", "group1")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInSeconds(10)
                        .RepeatForever())
                    .Build();

                // Tell quartz to schedule the job using our trigger
                scheduler.ScheduleJob(job, trigger);

                // some sleep to show what's happening
                Thread.Sleep(TimeSpan.FromSeconds(60));

                // and last shut down the scheduler when you are ready to close your program
                scheduler.Shutdown();
            }
            catch (SchedulerException se)
            {
                Console.WriteLine(se);
            }

            Console.WriteLine("Press any key to close the application");
            Console.ReadKey();
        }
    }

    public class HelloJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("Greetings from HelloJob!");
        }
    }
}

Upvotes: 1

jtabuloc
jtabuloc

Reputation: 2535

Here is the code of Hangfire Hosted in windows service @Devasish. For installation of hangfire and setup in window service refer to this link. Using hangfire you don't need to worry about timer event anymore. See example below.

using System.ServiceProcess;
using Hangfire;
using Hangfire.SqlServer;

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        private BackgroundJobServer _server;

        public Service1()
        {
            InitializeComponent();
            GlobalConfiguration.Configuration.UseSqlServerStorage("connection_string");
        }

        protected override void OnStart(string[] args)
        {
            _server = new BackgroundJobServer();

            // It will run everyday at 9:00.
            RecurringJob.AddOrUpdate<EmailService>( emailService => emailService.SendEmail() , "0 9 * * *");
        }

        protected override void OnStop()
        {
            _server.Dispose();
        }
    }
}

public class EmailService
{
    public void SendEmail()
    {
        // code for sending email here
    }
}

If you are not familiar with cron expresion 0 9 * * * for time scheduling you can check this link.I hope this will help you. :)

Upvotes: 0

Related Questions