1

所以我在 MVC 控制器方法中有以下代码:

public ActionResult ProcessFile () 
{
    ThreadStart threadStart = new ThreadStart ( ()=>{

        // Doing some long processing that takes 20 minute 
    } );

    Thread thread = new Thread(threadStart); 
    thread.Start();
}

这里的问题是,当向该控制器方法发送多个请求时,线程会被杀死。我需要 Thread 继续工作直到处理结束,这似乎是一个资源问题,占用的资源越多,线程可以继续工作的越少。如果我从 Windows 应用程序或服务运行该进程,它可以完美运行,只有从 Web 应用程序启动时才会出现问题。

4

2 回答 2

6

理想情况下,您不应在 IIS 7 中为 Web 请求创建线程(用于长时间运行的后台作业)。

如果应用程序池/AppDomain 重新启动,线程将停止,这可能由于多种原因而发生,例如 bin 文件夹内容的更改、web.config 的更改、一段时间的不活动、达到资源阈值(例如内存使用情况)。事实上,AppDomain 默认会定期重启,因为它已经存活了 x 时间。

出于这个原因,应该使用作业队列和后台作业运行程序来实现长时间运行的任务,例如控制台应用程序或 Windows 服务(重要的是,不在 IIS 的上下文中运行),处理这些作业。

Web 请求应该简单地将作业添加到队列中,允许后台作业运行器在作业出现时获取它们。

此处已回答了一个类似的问题我可以使用线程在 IIS 上执行长时间运行的作业吗?

编辑:严重不推荐的替代方案

如果您坚持或别无选择,只能在 IIS 进程中运行后台作业,您需要考虑允许后台作业自发停止,并允许它从停止时停止的地方重新启动。

您可以拥有一个可以轮询的 URL,以触发未完成作业的重新启动。

我过去看过这项工作,根据后台工作的要求,实现的复杂性会有所不同。

您会发现随着后台作业的反复启动和终止,服务器可能会开始出现性能问题。

于 2013-07-18T14:30:35.907 回答
0

虽然上面的答案是可以接受的,但在您的 Web 应用程序中托管任务等长期运行的服务还是有一些好处的。

Rick Strahl 在这里有一篇关于它的博客文章: Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive

于 2014-04-17T10:12:04.790 回答