ASP.NET长时间运行的任务。 线程正在中止exception

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分钟一个线程被中止exception被抛出。

有谁知道为什么会这样? 或者如何预防?

更多信息:

  • IIS标准配置。
  • 任务可以是任何内容,查询数据库和/或IO操作等。

更新:决定

谢谢大家的回复。 现在我不知道哪个问题要标记为答案。 所有这些都是有效的,并且可以解决这个问题。 将等待今天并以最高票数回答答案,如果是平局,我将选择第一个显示的答案,通常它们按最相关的顺序排序。

对于任何想要知道我选择的解决方案的人,再次由于时间限制,是改变IIS回收配置,但我认为是理想的解决方案,基于我的研究,当然下面的答案,是创建一个“工作服务”并使用ASP.NET应用程序和新的“工作服务”之间的通信解决方案来协调要完成的长时间工作。

您可以在自己的应用程序域中启动长时间运行的进程。

过去,当我需要此function时,我会为此创建一个Windows服务。 如果您使用WCF连接它,它甚至根本不必在IIS机器上运行; 您可以在网络上的任何计算机上运行它。

你有可能通过提高超时,使用不同的应用程序池或各种其他黑客来实现这一点,但最好的办法是将长时间运行的任务与ui和asp.net完全分离,然后使用服务(不推荐它)或轮询工作的计划任务; 我个人会使用像aws sqs / sns这样的东西来跟踪要完成的工作以及Windows服务器中的计划任务,它以任何合理的频率检查事物。 ui / asp.net唯一需要做的就是记录需要做某事的事实,而不是实际做的事情。

这种基于消息的方法的另一个好处是,如果长时间运行的进程变得如此长时间运行,或者过度工作,您将有机会添加更多工作任务或服务器来完成这些请求。

也许你可以为你的直接问题实施更多,但需要考虑更好的长期解决方案。