ASP.NET 3.5 webapp必须启动几个需要几个小时才能完成的任务。出于显而易见的原因,启动这些任务的页面不能等待它们完成,也不会有任何人想等待那么长时间来获得响应,因此任务必须是异步的。
有一个Helper类可以处理所有这些长时间运行的任务。计划和执行这些任务的主要方法如下:
public static bool ScheduleTask(TaskDescriptor task, Action action)
{
bool notAlreadyRunning = TasksAsync.TryAdd(task);
if (notAlreadyRunning)
{
Thread worker = null;
worker = new Thread(() =>
{
try { action(); }
catch(Exception e)
{
Log.LogException(e, "Worker");
}
TasksAsync.RemoveTask(task);
workers.Remove(worker);
});
workers.Add(worker);
worker.Start();
}
return notAlreadyRunning;
}
在早期的实现中,我们使用了ThreadPool.QueueUserWorkItem
方法但结果始终是相同的:在aprox之后。 20-30分钟a线程被中止异常被抛出。
有谁知道为什么会这样?或者如何防止它?
更多信息:
更新:决定
谢谢大家的回复。现在我不知道哪个问题要标记为答案。所有这些都是有效的,并且可以解决这个问题。将等待今天并以最高票数回答答案,如果是平局我将选择第一个显示的答案,通常它们按最相关的顺序排列。
对于任何想要了解我选择的解决方案的人,再次由于时间限制,是改变IIS回收配置,但我认为是理想的解决方案,基于我的研究,当然还有下面的答案,是创建一个“工作服务”,并使用ASP.NET应用程序和新的“工作服务”之间的通信解决方案来协调长时间运行的工作。
答案 0 :(得分:6)
您可以在自己的应用程序域中启动长时间运行的进程。
过去,当我需要此功能时,我会为此创建一个Windows服务。如果您使用WCF连接到它,它甚至不必在IIS机器上运行;你可以在网络上的任何机器上运行它。
答案 1 :(得分:4)
你有可能通过提高超时,使用不同的应用程序池或各种其他黑客来实现这一点,但你最好的选择是将长时间运行的任务与ui和asp.net彻底解耦,并使用服务(不推荐它)或轮询工作的计划任务;我个人会使用像aws sqs / sns这样的东西来跟踪要完成的工作,以及在Windows服务器中按照任何频率检查事情的计划任务。 ui / asp.net唯一需要做的就是记录需要完成某些事情的事实,而不是真正做到这一点。
这种基于消息的方法的另一个好处是,如果长时间运行的进程运行得太长,或者过度工作,您就有机会添加更多的工作任务或服务器来完成这些请求。
或许可以为您的直接问题实施,但需要考虑更好的长期解决方案。