tags:

views:

39

answers:

3

We need to send newsletter/messages to our users at certain times. This is done on the web; however, we want this to be done automatically for certain time. Although this problem suits the Window Service kind model, but we are hosting on public domain; therefore, we can't use this option.

Is there any way that this particular action can be invoked automatically at a certain point (time) specified in configuration in the web.config.

Currently this is done by manually invoked the operation through admin panel.

Platform - ASP.NET 3.5
Language - C#

A: 

Here's an example for using a timer in an ASP.NET application. You can check after the timer fires (or cache expires, if you go with that option) and see if you have gone past the time in web.config to invoke your event.

http://www.eggheadcafe.com/tutorials/aspnet/223319d8-6366-492a-8eae-e3c7a26c88a4/refreshing-aspnet--cache.aspx

Global.asax code (need to register System.Threading.Timer):

public class Global : HttpApplication
{
    private static Timer timer;
    private int interval = 60000*5; // five minutes


    protected void Application_Start(object sender, EventArgs e)
    {
        if (timer == null)
        {
            timer = new Timer(new TimerCallback(ScheduledWorkCallback), HttpContext.Current, interval, interval);
            ScheduledWorkCallback(HttpContext.Current);
        }
    }


    public static void ScheduledWorkCallback(object sender)
    {
        //do your work here
    }
}
Even Mien
Why the down vote?
Even Mien
+1 to compensate for the unexplained downvote.
Heinzi
+2  A: 

There's a simple solution to do stuff "every X time units". Although this is not exactly what you are looking for, it is amazingly simple to implement, so this might be a suitable workaround. (You could start a task every X minutes, which does some work if the current time is within some given time window.)

http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

The main idea is this (quoted from that link):

  1. At startup, add an item to the HttpRuntime.Cache with a fixed expiration.
  2. When cache item expires, do your work, such as WebRequest or what have you.
  3. Re-add the item to the cache with a fixed expiration.

BTW, this technique  is  was used for badge assignment here on Stackoverflow. :-)

Heinzi
it looks very cheeky idea and infect this might seem the solution to my problem. let me verified.
Gripsoft
That explains why the badge assignment is so flaky. :p
Aaronaught
Badge assignment no longer uses this technique (though it's true it once did - see Jeff Atwood's comment Feb 12th comment on that blog thread).
Jeff Sternal
@Jeff: Thanks for the update.
Heinzi
+1  A: 

It's possible to do this using a System.Threading.Timer, but you have to be very careful how you do it. You can run into all sorts of problems if you just throw in a timer the same way you would in a Windows service. A Windows service is alive for as long as it's running, and is single-threaded unless you make it multi-threaded; an ASP.NET AppDomain is neither.

This article has some good information about how to properly protect a timer. The main points are:

  • You need to serialize timer calls - don't allow re-entrancy in the callback, if one callback is already running then skip the next one;

  • You must dispose of the timer properly if the AppDomain is unloaded, which can happen for any number of different reasons.

So go ahead and use a System.Threading.Timer in your Application_Start method, but be mindful of these concerns and write appropriate protections into the code.

Aaronaught