Question

I'm writing a C# service and its main function is to pull photos from a database and save them to a directory twice a day. This operation takes about 15 minutes typically (there are a lot of photos). If I put the logic to run the program in OnStart(), then after a minute or so of starting up the service reports that it did not start up successfully. This is because it is in the OnStart() method for too long.

How can I set a timer in the OnStart() method that will call my RunApp() method after about a minute?

Edit: Here is some code. After setting up the scheduler that makes it run daily, I also want to just plain run it. I figured setting a timer for about a minute would work, that way it has time to get out of the OnStart() method. Then when the timer goes off the app will run.

protected override void OnStart(string[] args)
{
    Scheduler sch = new Scheduler("Photo Sync");

    try
    {
      MailConfiguration mailConfig = new MailConfiguration(Properties.Settings.Default.EmailLogTo, Properties.Settings.Default.EmailLogFrom,
                                                           "Photo Sync Photo Service error", Properties.Settings.Default.SmtpServerIp, "Photo Sync");
      sch.MailComponent = mailConfig;
    }
    catch
    {

    }

    sch.SchedulerFired += new EventHandler(RunApp);

    try
    {
      sch.ScheduleDaily(Properties.Settings.Default.DailyScheduledTime);
    }

    RunApp();
}
Was it helpful?

Solution

Run the save functionality in a separate thread that you start in the OnStart method of your service. Something like this:

protected override void OnStart(string args[])
{

    // your other initialization code goes here

    // savePhotos is of type System.Threading.Thread
    savePhotosThread = new Thread(new ThreadStart(SavePhotos));
    savePhotosThread.IsBackground = true;
    savePhotosThread.Name = "Save Photos Thread";
    savePhotosThread.Start();

}

You'll place the functionality for saving the files in the `SavePhotos` method, maybe something like this:

private void SavePhotos()
{

    // logic to save photos
}

I've used code similar to the above to do logging (I log stats for the service every 5 minutes or so) for an always-on service I wrote a few years back. Don't forget to add System.Threading to your service and the using directive.

OTHER TIPS

Typically, the normal process to starting a Windows Service is to make a thread, and have that thread perform the service processing, allowing OnStart to exit timely for Windows. The thread is still in the background processing things. For example:

protected CancellationTokenSource _tokenSource = null;

protected override void OnStart(string[] args)
{
    _tokenSource = new CancellationTokenSource();

    Task processingTask = new Task(() =>
       {
           while(!_tokenSource.IsCancellationRequested)
           {
               // Do your processing
           }
       });

    processingTask.Start();
}

protected override void OnStop()
{
    _tokenSource.Cancel();
}

If your service does not need to be running indefinitely, then you might want to consider a scheduled task.

    System.Threading.Timer Timer1 = new System.Threading.Timer(RunApp, null, 1000, System.Threading.Timeout.Infinite);

void RunApp(object State)
{
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top