我有一个类似的问题,我正在开发一个 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。这是一个 hack,ASP 并不意味着运行后台任务,所以尽可能使用 Windows 服务或 WCF 服务!我使用它是因为它简化了开发、维护和安装。
有关更多信息,请参阅我的来源:http ://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx