What is the best way to call/start a Windows Service every x seconds?

五迷三道 提交于 2019-12-06 17:46:27

Sleeping is usually a bad idea. Apart from anything else, it means that you won't respond to the Stop event quickly.

You should use a Timer. There are two which are appropriate for services:

In each case you basically say what you want to happen each time the timer "ticks" and when you want it to fire.

My threading tutorial has a section explaining some of the differences between available timers.

I'm not sure about your WCF question, but I don't think your web service would be explicitly starting the service - it would just be contacting it via WCF. Yes, you'd potentially need to be careful about threads. Exactly what you'll need to be careful of will depend on what the WCF service is exposing.

Basic System.Threading.Timer code:

// Class level variable in the Windows Service:
private System.Threading.Timer timer;

// This is in the constructor for a Windows Service.
// interval would be the time in milliseconds in between ticks.
// 0 is how long until it should start.
timer = new Timer(new TimerCallback(TimerElapsed), null, 0, interval);

// The TimerCallback in the Windows Service:
private void TimerElapsed(object o)
{
    // Do email stuff here.
}

If you want to have it run as a service (in the background, without anyone logged in), yes, this is one way to do it.

Another would be to have a Timer that calls its "Tick" event handler every 5 seconds or so.

Or if your checks aren't quite as frequent, you could also create a command-line console app and just schedule it as a "scheduled task" in Windows.

Marc

Your code has the problem of adding to the call stack for every call, since you call the method from within itself. At some point you will get a stack overflow exception. One wait is to call another method on a "waiting thread" that will signal back after a certain time:

private void CheckMailBox()
{
    _waitHandle = new AutoResetEvent(true);
    while (_waitHandle.WaitOne())
    {
        // do the mail checking
        ((IDisposable)_waitHandle).Dispose();
        _waitHandle = new AutoResetEvent(false);
        ThreadPool.QueueUserWorkItem(WaitSomeTime, 2000);
    }

}

private void WaitSomeTime(object state)
{

    Thread.Sleep((int)state);
    _waitHandle.Set();
}

A possible enhancement beyond using a timer would be to use a scheduling component in your service. Then you could setup your service to be the host for the code that would access your mailbox.

Quartz.NET is an open source scheduling component that can do this. It allows you to setup the scheduling exactly as you want and it is quite easy to use.

Ok, while your timing question is pretty much handled (and i would agree with most of the above), I can offer some info concerning WCF. A WCF service is simply hosted within an application domain. This domain could be a windows form, console application, ASP.net and in this case, a Windows Service.

So in a sense, you're not exposing the windows service via WCF, you're more hosting the WCF service within a Windows Service application domain. I would advise testing your service (timer objects included) in a windows form before making the transition to windows service. Easier to debug and test.

A hosted WCF service is in fact running in its own thread:

    serviceType_MyEmailer = typeof(MyEmailerServiceType);
    ServiceHost host_MyEmailer;


    host_MyEmailer = new ServiceHost(serviceType_MyEmailer);

Look for a "DerivativesCalculatorService" example online. Shows you how to host a WCF service in code.

The timing trick here is in within your service itself. You could create your service class to be a singleton class that gets initialized immediately, and upon its initialization it could start its Timer object (as seen with the other answers).

In this way, your WCF service would have a persistent instance of your class with its Timer object silently ticking off. Have all of that hosted in a Windows Service and you're done.

Hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!