5

My question is that is this the best practice to do this. Couldn't find any good examples. I have following code in file created by VS2005:

public partial class ObjectFolder : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        ObjectFolderApp.Initialize();

        ObjectFolderApp.StartMonitorAndWork();
    }

    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop yourservice.
    } 
}

then:

class ObjectFolderApp
{
    public static bool Initialize()
    {
        //all init stuff
        return true;
    }


    public static void StartMonitorAndWork()
    {
        Thread worker = new Thread(MonitorAndWork);
        worker.Start();
    }


    private static void MonitorAndWork()
    {
        int loopTime = 60000;
        if (int.TryParse(_cfgValues.GetConfigValue("OfWaitLoop"), out loopTime))
            loopTime = 1000 * loopTime;

        while (true)
        {
            /* create+open connection and fill DataSet */
            DataSet ofDataSet = new DataSet("ObjectFolderSet");
            using (_cnctn = _dbFactory.CreateConnection())
            {
                _cnctn.Open();

                //do all kinds of database stuff
            }
            Thread.Sleep(loopTime);
        }
    }
}
radbyx
  • 9,352
  • 21
  • 84
  • 127
char m
  • 7,840
  • 14
  • 68
  • 117

2 Answers2

14

Re-hashing my answer from this question, the recommended way is to use a timer and the following code:

public class MyService : ServiceBase
{
    private Timer workTimer;    // System.Threading.Timer

    protected override void OnStart(string[] args)
    {
        workTimer = new Timer(new TimerCallback(DoWork), null, 5000, 5000);
        base.OnStart(args);
    }

    protected override void OnStop()
    {
        workTimer.Dispose();
        base.OnStop();
    }

    private void DoWork(object state)
    {
        RunScheduledTasks();  // Do some work
    }
}

Simple!

Note that the Timer type being used is System.Threading.Timer, same as Justin specifies.

Community
  • 1
  • 1
Aaronaught
  • 120,909
  • 25
  • 266
  • 342
  • 1
    The above code works like a charm. I'm using in a windows service to check a queue. – Chuck Conway Apr 07 '10 at 15:18
  • thanks! ...hmmm... so you suggest I don't even call ObjectFolderApp.Initialize(); in OnStart?? It has to be initialized only once. Another question is calling overrided base methods. Why is that? – char m Apr 07 '10 at 15:47
  • @matti: I don't know what you're doing in `Initialize`, so it's hard to say. You might still need it. As for calling the base methods, you don't necessarily have to, but as a general rule it's a good idea if what you're trying to do is *extend* the base class logic as opposed to *replace* it (which is the desired semantic here). – Aaronaught Apr 07 '10 at 16:07
  • Initialize is for reading configuration file etc. the normal init tasks. – char m Apr 07 '10 at 16:11
  • 1
    look at this answer http://stackoverflow.com/questions/10441368/prevent-multiple-instance-of-a-service-best-approach handles the situation where the action takes longer then the interval – Avi Pinto May 10 '12 at 12:43
3

Use a System.Threading.Timer to fire the process off at the scheduled interval.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536