views:

29

answers:

2

I'm new to WCF, so maybe this is something best done in another way.

Right now I have a collection of WCF Services, but I am trying to build in functionality which sends weekly emails. To do this I built another WCF service with the code below:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, AutomaticSessionShutdown = false)]
public class TimerService : ITimerService
{
    private static Timer timer;
    private static TimeSpan tSpan = new TimeSpan(0, 0, 20, 0);
    private static OtherService Ref = new OtherService();

    public void ToggleEmailTimer(bool enabled)
    {
        if (enabled)
            timer = new Timer(new TimerCallback(TimerElapsed), null, tSpan, tSpan);
        else
        {   
            if(timer != null)
                timer.Dispose();
        }
    }

    private void TimerElapsed(object state)
    {
        Ref.SendWeekly();
    }
}

It begins disabled, and I enable it from an aspx page.For testing, I've managed to make this work for 10 minutes intervals, and it seems to break somewhere around setting the interval to 15 minutes.

To me, it seems like the WCF Serivce session is expiring from inactivity, which would explain why the timer just stops. Is there a way to specify the lifetime of the WCF Service so that I could enabled the timer from the aspx page, exit, and the timer service will persist? I have seen information about setting timeout values but it is still unclear to me if this applies.

A: 

This most likely has to do with the host process and not the WCF instance context behavior. A "Single" instance context should live for as long as the host process lets it. But IIS by default will recycle worker processes upon various conditions. These conditions can include a maximum lifetime of even a healthy process, but also memory footprint and latency during health checks can cause IIS to kill the process.

While you could play with the IIS configuration or create a custom host process that you intend to be long-running, this is not a good scenario for WCF at all.

Even a standard Windows Service process seems like overkill for something that is supposed to act weekly. Why not just schedule a task using the Windows Task Scheduler? If it's part of a long-running workflow, perhaps you should consider looking into Windows Workflow Foundation.

Josh Einstein
If I go that route, the issue is how I run my code within the TimerElapsed method. This is being run on another web service. Is there an easy way to do that in a script (maybe powershell)? How would I use the task scheduler to run that web service method?
BTmuney
+1  A: 

The others are correct that you do not want to use WCF for the actual task scheduling. While it is theoretically possible to fiddle with the app pool recycling, it is definitely not the ideal route. Using windows task scheduling would be a fine solution. The easiest way to accomplish this is to expose your WCF services via REST (by using Factory="System.ServiceModel.Activation.WebServiceHostFactory" in your .svc file.) That way, you can have Windows task scheduling invoke your service by accessing a URL.

Kirk Woll