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"来协调要完成的长时间运行的工作

ASP.NET长时间运行任务.线程被中止异常

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

在过去,当我需要这个功能时,我为此目的创建了一个Windows服务。如果你使用WCF来连接它,它甚至不需要在IIS机器上运行;您可以在网络上的任何机器上运行它。

有可能你可以通过提高超时,使用不同的应用程序池或各种其他技巧来实现此工作,但你最好的选择是将长时间运行的任务与ui和asp.net完全分离,并使用服务(不建议使用)或轮询工作的计划任务;就我个人而言,我会使用aws sqs/sns之类的东西来跟踪要完成的工作,并在windows服务器中检查要做的事情,无论频率如何都有意义。ui/asp.net需要做的唯一一件事就是记录需要做的事情,而不是实际去做。

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

对于当前的问题,也许比你能实现的要多,但对于一个更好的长期解决方案,这是值得考虑的。