Windows Service job

RadhaKrishnaKiJaya
RadhaKrishnaKiJaya used Ask the Experts™
on
Coding in ASP.NET and C#

Hello Experts,
I am trying to run a Windows Service job only once everyday at a time specified in App.Config file.  How can I use make use of Timer class?  As soon as the job is done, the job will go to sleep mode and again wake up next day.  Is there a simple way?

Here is the requirement.

 1. Process Schedule Task
    Add code to Process the task here
    .
    .

 2. Once the job is executed, reset next run to every 24 hours

Thank you very much in advance!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Chinmay PatelChief Technology Ninja
Distinguished Expert 2018

Commented:
Hi RadhakrishnaKiJaya,

How about using Windows Scheduler?
https://docs.microsoft.com/en-us/windows/win32/taskschd/schtasks OR Task Scheduler App (which is part of Windows) for that matter.

Regards,
Chinmay.
You could do this pretty easily,


if (yourtimecheck("5:44 AM")) {
 //do stuff then pause the thread to avoid running more than once
//Thread.Sleep(60000);
 } 

public bool yourtimecheck(string yourtime){
 if (yourtime == DateTime.Now.ToString("t")) {return true;}
 else {return false;}
  }

Open in new window


System.Threading Timer Class
https://docs.microsoft.com/en-us/dotnet/api/system.threading.timer?view=netframework-4.8

Commented:
Personally I wouldn't put the tread to sleep.  Rather, I would use a regular timer and subscribe to the timer elapsed event.  On elapse of the timer, then I would check the current time against your preferred time as illustrated by hilltop.  Something like (quick and dirty):

Service1.cs -
using System;
using System.Configuration;
using System.ServiceProcess;

namespace EE_Q29169025
{
    public partial class Service1 : ServiceBase
    {
        private string yourTime = default(string);

        public Service1()
        {
            InitializeComponent();
            yourTime = ConfigurationManager.AppSettings.Get("YourTime");
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }

        private void OnElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(yourTime) && YourTimeCheck(yourTime))
            {
                // Do something
            }
        }

        bool YourTimeCheck(string time)
        {
            var run = default(DateTime);
            var now = DateTime.Now;

            if (DateTime.TryParse(time, out run) && Equals(run.Hour, now.Hour) && now.Minute >= run.Minute)
            {
                timer1.Interval = TimeSpan.FromHours(24).TotalMilliseconds;
                return true;
            }
            return false;
        }
    }
}

Open in new window

Service1.Designer.cs -
namespace EE_Q29169025
{
    partial class Service1
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.timer1 = new System.Timers.Timer();
            ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
            // 
            // timer1
            // 
            this.timer1.Enabled = true;
            this.timer1.Interval = 3000D;
            this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.OnElapsed);
            // 
            // Service1
            // 
            this.ServiceName = "Service1";
            ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

        }

        #endregion

        private System.Timers.Timer timer1;
    }
}

Open in new window

-saige-

Author

Commented:
Thank you saige, hilltop and Chinmay for your help.

Below is my current code, where it keeps trying for 3 time in every 2 seconds.  Sometime I feel it interrupts the processing in between, as a result process restarts from the beginning.

My requirement is it should start the job and not to interrupt in the middle.  Once the job is done, program should exit.  Otherwise it can keep trying 3 times.  Please see if you can help.

Thank you again!  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using log4net;


namespace XXX_Import_Service
{
    class Expert_Exchange
    {
        string strDate;
        private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static Timer fileTimer = new Timer();

        protected override void OnStart(string[] args)
        {
            log4net.Config.DOMConfigurator.Configure();

            fileTimer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
            fileTimer.Interval = 20000;
            fileTimer.Enabled = true;
        }

        private void OnElapsedTime(object source, ElapsedEventArgs e)
        {
            string serviceRunTime = System.Configuration.ConfigurationSettings.AppSettings["frequency"];
            if (strDate != System.DateTime.Now.ToShortDateString() && (DateTime.Now.ToShortTimeString() == serviceRunTime))
            {
                if (XXX_Import())
                {
                    log.Debug("OnElapsedTime: File Imported successfully");
                    // Once XXX_Import() is complete, I would like to exit from here.
                }
                else
                {
                    log.Debug("OnElapsedTime: File Import failed");
                }
                strDate = DateTime.Now.ToShortDateString();
            }
        }

        protected override void OnStop()
        {
            //System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStop.txt");
        }

        public static bool XXX_Import()
        {
            log.Debug("XXX_Import - Import Started: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
            .
            .
            .
        }
    }
}

Commented:
program should exit
That is not how services work.  Services, by definition, are continuously running programs which perform background tasks.  They run regardless of whether a user is logged into the computer.

If you still want to use a service.  You need to have logic which will perform your task within the constraints of your requirements.  Otherwise it sounds like you need to create a console or forms based application which will be triggered using the Task Scheduler.

-saige-

Author

Commented:
Hello saige,
Not to confuse you.  This is not the entire code.  This is the just the main portion and it works.  It runs continuously and It starts on time too.  Unfortunately it does not work the way I expect.

Thank you!
I created an ActiveStatus flag and used it.  Whenever the ActiveStatus is true, it would not fire.  With that everything works as expected.

Thank you.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial