Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recurring tasks in ASP .NET

I have an ASP .NET website running on GoDaddy in a shared environment. The application is a subscription-based service with options for recurring billing to users.

Every hour, we need to synchronize user data with our payment processor to update users who have upgraded or cancelled their accounts. The payment processor, does not have a mechanism for calling a URL or otherwise notifying us of changes.

The problem: We need to create a background thread that runs some code at a predefined interval. There are some good articles about background tasks in .NET but I am sure, there could be a simpler way around this. Maybe an application-wide timer that can call a function, etc.

The limitation: Shared environment does not allow windows services, external applications, full-trust, etc.

Since this is a production application, I would like to use the safest approach possible rather than arm-twisting IIS.

like image 952
Raheel Khan Avatar asked Dec 29 '11 11:12

Raheel Khan


People also ask

What are recurring tasks?

Recurring tasks are tasks that happen over and over again, on a regular basis. For instance, as a project manager, it's common to have regularly scheduled reporting intervals.

What is the difference between task and a recurring task?

Recurring Tasks are the tasks that happen on a regular basis. When you mark a task complete, the next task is automatically generated based on the repeating pattern you set up.

What is a recurring task provide an example of a recurring task?

Some recurring tasks allow you to create tasks that repeat only if you've completed a prior task. For example, you may have a task that doesn't have a dated deadline but follow up after something else, like an appointment or check-up.


2 Answers

I had a similar problem, I'm developing a ASP proof of concept and use a background thread that performs a task that could take several hours. Problem is, ASP.Net can recycle the AppDomain at anytime (killing my background thread).

To prevent this, you can register your background thread to ASP.Net so it will notify your thread to shut down. To do this implement the following interface:

public interface IRegisteredObject
{
    void Stop(bool immediate);
}

And register your object to ASP using the following static method:

HostingEnvironment.RegisterObject(this);

When ASP.NET tears down the AppDomain, it will first attempt to call Stop method on all registered objects. In most cases, it’ll call this method twice, once with immediate set to false. This gives your code a bit of time to finish what it is doing. ASP.NET gives all instances of IRegisteredObject a total of 30 seconds to complete their work, not 30 seconds each. After that time span, if there are any registered objects left, it will call them again with immediate set to true.

By preventing the Stop method from returning (by locking a field when the worker is busy), we stop ASP from shutting down the AppDomain until our work is finished.

public void Stop(bool immediate)
{
    lock (_lock)
    {
        _shuttingDown = true;
    }
    HostingEnvironment.UnregisterObject(this); 
}

public void DoWork(Action work)
{
    lock (_lock)
    {
        if (_shuttingDown)
        {
            return;
        }
        work();
    }
}

Use a Task instead of action to benefit from cancellation options. For your specific case you could start a timer that executes tasks like this.

PS. This is a hack and ASP isn't meant to run background tasks so use a windows service or WCF service when possible! I use this since it simplifies development, maintenance and installation.

For more information see my source: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

like image 178
Rob Avatar answered Oct 13 '22 11:10

Rob


To update for 2018 - The Hangfire NuGet package is perfect for this

like image 21
niico Avatar answered Oct 13 '22 12:10

niico