ASP.NET长时间运行任务.线程被中止异常
本文关键字:异常 线程 任务 NET 长时间 运行 ASP | 更新日期: 2023-09-27 18:11:04
. NET 3.5 web应用程序必须启动几个需要几个小时才能完成的任务。由于明显的原因,启动这些任务的页面不能等待它们完成,也没有人想要等待那么长时间来获得响应,因此任务必须是异步的。
有一个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
方法,但结果总是相同的:在大约x之后。20-30分钟抛出一个线程被中止异常。
有人知道为什么会这样吗?或者如何预防?
更多信息:
- IIS标准配置。
- 任务可以是任何东西,查询数据库和/或IO操作等。
更新:决策/strong>
谢谢大家的回复。现在我不知道该把哪个问题标记为答案。它们都是有效的,都是这个问题的可能解决方案。我会等到今天,并标记为答案的答案与最多的投票,在平局的情况下,我将选择第一个显示的答案,通常他们是按最相关的排序。
对于那些想知道我选择的解决方案的人,同样由于时间限制,是改变IIS回收配置,但我认为最理想的解决方案,根据我的研究和下面的答案,是创建一个"Worker服务",并在ASP. js . js之间使用通信解决方案。. NET应用程序和新的"Worker Service"来协调要完成的长时间运行的工作
您可以在其自己的应用程序域中启动长时间运行的流程。
在过去,当我需要这个功能时,我为此目的创建了一个Windows服务。如果你使用WCF来连接它,它甚至不需要在IIS机器上运行;您可以在网络上的任何机器上运行它。
有可能你可以通过提高超时,使用不同的应用程序池或各种其他技巧来实现此工作,但你最好的选择是将长时间运行的任务与ui和asp.net完全分离,并使用服务(不建议使用)或轮询工作的计划任务;就我个人而言,我会使用aws sqs/sns之类的东西来跟踪要完成的工作,并在windows服务器中检查要做的事情,无论频率如何都有意义。ui/asp.net需要做的唯一一件事就是记录需要做的事情,而不是实际去做。
这种基于消息的方法的另一个好处是,如果长时间运行的流程变得非常长,或者过度工作,您将有机会添加更多的工作任务或服务器来完成这些请求。
对于当前的问题,也许比你能实现的要多,但对于一个更好的长期解决方案,这是值得考虑的。