【问题标题】:Recurring tasks in ASP .NETASP .NET 中的重复任务
【发布时间】:2011-12-29 11:04:43
【问题描述】:

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

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

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

限制:共享环境不允许windows服务、外部应用、全信任等。

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

【问题讨论】:

  • 是的,我知道 Quartz。我正在寻找一个不依赖于外部许可证、商业或开源的自定义解决方案。
  • 您如何从您的提供商那里获取数据?您说“没有调用 URL 的机制”。你是说他们不能给你打电话,还是你不能给他们打电话,或者两者兼而有之?
  • 我的意思是,每次与支付处理器进行交易时,他们都不会通知我们。我们必须轮询他们的数据库。为了轮询它们,我们需要某种计划任务。

标签: asp.net iis background task recurring


【解决方案1】:

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

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

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

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

HostingEnvironment.RegisterObject(this);

当 ASP.NET 拆除 AppDomain 时,它将首先尝试对所有已注册对象调用 Stop 方法。在大多数情况下,它会调用此方法两次,一次将 immediate 设置为 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。这是一个 hack,ASP 并不意味着运行后台任务,所以尽可能使用 Windows 服务或 WCF 服务!我使用它是因为它简化了开发、维护和安装。

更多信息见我的消息来源:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

【讨论】:

  • 晚了一年,但我喜欢这个解决方案,并将在当前项目中尝试它。谢谢。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    由于没有答案,我想我会发布我的解决方案以防它帮助其他人。

    无论如何都不是理想的方法,但对于那些可能从中受益的人来说,我在另一个 Linux 主机帐户上创建了一个 cron 作业,我们必须调用所需的 ASP .NET url。管理恐怖,但确实有效。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多