Question

I'm working on an ASP.NET MVC application where I need to keep updating a file in a time-interval. I will eventually be hosting this website on Windows Azure.

I was just wondering if the approach mentioned in Phil Haack's post The Dangers of Implementing Recurring Background Tasks In ASP.NET is still the best approach or if I should look into creating a console app or so and use Azure Web Jobs to run it?

Any thoughts appreciated.

Thanks, Daniel

No correct solution

OTHER TIPS

You can do something like this:

    private void AddHourlyTask(string task)
    {

        DateTime expiration = DateTime.Now.AddHours(1);
        expiration = new DateTime(expiration.Year, expiration.Month, expiration.Day, expiration.Hour, expiration.Minute, expiration.Second, expiration.Kind);

        OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
        HttpRuntime.Cache.Insert(
            task,
            task,
            null,
            expiration,
            Cache.NoSlidingExpiration,
            CacheItemPriority.NotRemovable,
            OnCacheRemove);
    }

And then in a separate function:

    public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
    {
        if (k == "HelloWorld")
        {
            Console.Write("Hello, World!");
            AddHourlyTask(k);
        }

This would go into your Application_Start() function as:

AddHourlyTask("HelloWorld");

In order for this to work, you also need to add this somewhere in your class:

private static CacheItemRemovedCallback OnCacheRemove = null;

The functions would all sit in your Global.asax.cs file

You might look at scheduling a simple console app, batch file, perl script, etc. with the windows task scheduler. Depending on what it needs to do, it could be as simple as invoking a web method in your ASP.Net MVC web app.

One option is looking into Quartz.

Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.

I asked a similar question on Programmers: How do I make my ASP.NET application take an action based on time?

Accepted Answer:

A scheduled task triggered by either the Task Scheduler or Sql Server is the way to go here. But if you really want to manage it within your webapp, you might want to look at something like Quartz.NET. It will let you do scheduled tasks from the CLR. Then your challenge is "how do I make sure the AppDomain stays up to run the tasks."

Another way to do it as a scheduled task yet keep most of the "smarts" on the server is to make it a task that can be called over HTTP with some sort of authorization key. This lets you write a relatively simple program to call it -- if not a simple shell script -- and to keep most of the complexity in the web app which is likely already capable of running the task.

Either way rolling your own task manager is really a path fraught with peril.

Scheduling tasks in an ASP.NET MVC project is possible using the Revalee open source project.

Revalee is a service that allows you to schedule web callbacks to your web application). In your case, you would schedule a callback that would perform your desired action (i.e., update a file). Revalee works very well with tasks that are discrete transactional actions, like updating a database value or sending an automated email message (read: not long running). The code to perform your action would all reside within your MVC app. When your application launches for the very first time, then you would schedule the first web callback. When your application is called back to generate the report, then you would schedule the next callback.

To use Revalee, you would:

  1. Install the Revalee Service, a Windows Service, on your server. The Windows Service is available in the source code (which you would compile yourself) or in a precompiled version available at the Revalee website.

  2. Use the MVC-specific Revalee client library in your Visual Studio project. (There is a non-MVC version too.) The client library is available in the source code (which, again, you would compile yourself) or in a precompiled version available via NuGet.

  3. You would register a future callback when your application launches for the very first time via the ScheduleHourlyCallback() method (this example is assuming that you need your action to run once per hour).

    private void ScheduleHourlyCallback()
    {
        // Schedule your callback for an hour from now
        var callbackTime = DateTimeOffset.Now.AddHours(1.0);
    
        // Your web app's Uri, including any query string parameters your app might need
        Uri callbackUrl = new Uri("http://yourwebapp.com/Callback/UpdateFile");
    
        // Register the callback request with the Revalee service
        RevaleeRegistrar.ScheduleCallback(callbackTime, callbackUrl);
    }
    
  4. When Revalee calls your application back, your app would perform whatever action you have coded it to do and your app schedules the next callback too (by calling the ScheduleHourlyCallback() method from within your controller's action).

I hope this helps.

Note: The code example above uses a synchronous version of ScheduleCallback(), the Revalee client library also supports asynchronous calls à la:

RevaleeRegistrar.ScheduleCallbackAsync(callbackTime, callbackUrl);

Disclaimer: I was one of the developers involved with the Revalee project. To be clear, however, Revalee is free, open source software. The source code is available on GitHub.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top