views:

69

answers:

4

Hi, can someone let me know how to run a long running process from a windows service (in C#)? the process may take hours to finish. the service should check the database for any pending jobs to execute. each job can take any long to finish. if there are no pending jobs, then it should sleep for 2mins (configurable) and then start again. how can I do this using a windows service? Thanks in advance.

A: 

There's no special trick to it, except you can't use any GUI/Forms or user input. A windows service by definition has no user I/O. Write errors to the event log and you're fine.

Jay
I can't put a never ending loop in the start method for the service, otherwise the service won't start. so I was looking for some mechanism to trigger the job processing code every few minutes. I managed to do this using Timer component and setting its interval, but then I had to stop the timer from ticking when the process is running. I achieved this by disabling the timer before starting the process and enabling it after the process is finished. thanks for your reply.
RKP
try this: System.Threading.Thread.Sleep(2 * 60 * 1000);
Jay
A: 

It is a lot easier to use windows scheduled tasks than develop your own app, you should give it a try.

If it doesn't work the way you expect, as Jay said, there's no trick, just remember there's no GUI.

Gmoliv
this service needs to wake-up every two minutes and my company IT policy doesn't allow scheduled task to have sleeping time less than 10 mins. so I had to choose windows service option. it would have been much easier with a console app, easy to debug. thanks for the reply
RKP
+1  A: 

you have to create console apps something like this

static void Main(string[] args)

    {
       bool createdNew;
        Mutex m = new Mutex(true, "YourBatchProcessor", out createdNew);
        if (!createdNew)
        {
             Console.WriteLine("YourBatchProcesso is already running!");
            return;
        }
        //your code goes here

    }

and as Gmoliv said create scheduled tasks than run every 2 minutes

or if you want to write window service then your service code like

public class YourServrClass {

    private int numticks = 0;
    private Timer _timer;
    private bool _IsStarted;
    private int Interval =2000; //ticks //2 sec.
    #region Initializer
    public YourServrClass()
    {
        InitializeComponent();
        _timer = new Timer();
         _timer.Interval = Interval;
        _timer.Elapsed += new ElapsedEventHandler(this.Timer_Tick);
    }
    #endregion

    #region Timer_Tick to process

    private void Timer_Tick(object sender, System.Timers.ElapsedEventArgs e)
    {
        numticks++;
        if (_IsStarted)
        {
            _timer.Stop();

            //your code //ProcessYourData();
            _timer.Start();
        }
    }
    #endregion
    protected override void OnStart(string[] args) 
    { 
           _IsStarted=true;
    } 

    protected override void OnStop() 
    { 
          _IsStarted=false;
    } 

}

Hasu
thanks for the reply. I resolved it by using Timer component as well, but my code is a bit different. I start the timer in "OnStart" method, stop it in "OnStop" method and in "Elapsed" event handler I disable the timer just before running the process, and re-enable it after the process is finished. it works now.
RKP
A: 
  1. Create a new "Windows Service" project.
  2. Override OnStart method to create either a thread. This thread will handle the polling and processing.
  3. Override the OnStop method to set a flag. The thread from step 2 watch for this flag and terminate itself accordingly.
  4. Open the design surface of the Service class. At the bottom of the Properties window is a link called "Add Installer". Click it.
  5. Install the suervice using InstallUtil or by putting it inside an installer package.

I write services all the time, so feel free to ask me follow-up questions.

Jonathan Allen
I actually don't like the service option, because it keeps hitting the DB every two mins to check if there is any job to execute and it is wastage of CPU time when there are none to execute. instead I like event-driven model by which process wakes up only when there is a pending job to execute. I think it is possible with MSMQ, but I am not familiar with it, need to find out how to use it. thanks for the reply. this process should be able to spawn multiple threads to save time in executing multiple pending jobs. there is also a requirement to kill the process if it is taking longer than usual
RKP
Funny you should mention MSMQ. I actually have SQL Server send MSMQ messages when there is work to be done. By service then watches the queue. Once in a very rare while I will lose a single MSMQ message, but that only happens when I'm sending tens of thousands of messages in a few seconds.
Jonathan Allen