ASP .NET中的重复任务

Rah*_*han 4 asp.net iis background recurring task

我在共享环境中的GoDaddy上运行了一个ASP .NET网站.该应用程序是一种基于订阅的服务,具有向用户重复计费的选项.

每小时,我们都需要将用户数据与我们的支付处理器同步,以更新已升级或取消其帐户的用户.支付处理器没有用于调用URL或以其他方式通知我们更改的机制.

问题:我们需要创建一个后台线程,以预定义的间隔运行一些代码.在.NET中有一些关于后台任务的好文章,但我相信,这可能有一个更简单的方法.也许是可以调用函数等的应用程序范围的计时器.

限制:共享环境不允许Windows服务,外部应用程序,完全信任等.

由于这是一个生产应用程序,我想尽可能使用最安全的方法,而不是绞尽脑汁的IIS.

Rob*_*Rob 5

我有一个类似的问题,我正在开发一个ASP概念证明并使用后台线程执行可能需要几个小时的任务.问题是,ASP.Net可以随时回收AppDomain(杀死我的后台线程).

为了防止这种情况,您可以将后台线程注册到ASP.Net,以便它通知您的线程关闭.为此,请实现以下界面:

public interface IRegisteredObject
{
    void Stop(bool immediate);
}
Run Code Online (Sandbox Code Playgroud)

并使用以下静态方法将对象注册到ASP:

HostingEnvironment.RegisterObject(this);
Run Code Online (Sandbox Code Playgroud)

当ASP.NET删除AppDomain时,它将首先尝试在所有已注册的对象上调用Stop方法.在大多数情况下,它会调用此方法两次,一次立即设置为false.这为您的代码提供了一些时间来完成它正在做的事情.ASP.NET为IRegisteredObject的所有实例提供了总共30秒的时间来完成工作,而不是每个30秒.在该时间跨度之后,如果剩下任何已注册的对象,它将立即再次调用它们并立即设置为true.

通过阻止Stop方法返回(通过在工作者忙时锁定字段),我们停止ASP关闭AppDomain,直到我们的工作完成.

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

public void DoWork(Action work)
{
    lock (_lock)
    {
        if (_shuttingDown)
        {
            return;
        }
        work();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用任务而不是操作来从取消选项中受益.对于您的特定情况,您可以启动一个执行此类任务的计时器.

PS.这是一个黑客攻击,ASP并不意味着运行后台任务,所以尽可能使用Windows服务或WCF服务!我使用它,因为它简化了开发,维护和安装.

有关更多信息,请参阅我的来源:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx