我在共享环境中的 GoDaddy 上运行了一个 ASP .NET 网站。该应用程序是一种基于订阅的服务,具有向用户定期计费的选项。
每小时,我们都需要与我们的支付处理器同步用户数据,以更新已升级或取消帐户的用户。支付处理器没有调用 URL 或以其他方式通知我们更改的机制。
问题:我们需要创建一个后台线程,以预定义的时间间隔运行一些代码。有一些关于 .NET 中后台任务的好文章,但我敢肯定,可能有更简单的方法来解决这个问题。也许是一个可以调用函数的应用程序范围的计时器等。
限制:共享环境不允许windows服务、外部应用程序、完全信任等。
由于这是一个生产应用程序,我想使用最安全的方法,而不是使用 IIS。
最佳答案
我有一个类似的问题,我正在开发一个 ASP 概念证明并使用一个后台线程来执行可能需要几个小时的任务。问题是,ASP.Net 可以随时回收 AppDomain(杀死我的后台线程)。
为了防止这种情况,您可以将您的后台线程注册到 ASP.Net,以便它会通知您的线程关闭。为此,请实现以下接口(interface):
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
关于asp.net - ASP .NET 中的重复任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8667062/