ASP .NET中的重复任务

时间:2011-12-29 11:04:44

标签: asp.net iis background task recurring

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

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

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

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

由于这是一个生产应用程序,我想使用最安全的方法而不是扭曲IIS。

3 个答案:

答案 0 :(得分:5)

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

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

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

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

HostingEnvironment.RegisterObject(this);

当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();
    }
}

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

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

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

答案 1 :(得分:1)

要更新2018年 - Hangfire NuGet包非常适合此

答案 2 :(得分:0)

由于没有答案,我认为我会发布我的解决方案以防其他人。

不是理想的方法,但对于那些可能从中获益的人,我在另一个Linux主机帐户上创建了一个cron作业,我们必须调用所需的ASP .NET URL。管理恐怖,但做的工作。