网页执行长任务而不会超时

时间:2016-01-04 23:06:42

标签: asp.net asp.net-mvc-5 .net-4.5.2

我们的网站有一个管理页面,允许管理员启动将给定模板CMS页面复制到几百个目录的过程。我想这个过程需要几分钟才能运行,因此页面超时。所以我认为我们需要它做的是让提交按钮启动任务,然后每隔X秒对结果进行页面轮询,直到完成为止。

我一直在试图弄清楚如何做到这一点并看到Phil Haack's popular "Dangers of Implementing Recurring Background Tasks in ASP.NET"帖子。虽然可以做出一个不错的论点,即外部应用程序应该执行此工作而不是Web服务器,但实际上它不会经常使用,管理员需要Web界面,并且我们已经有了一个工作版本代码,浏览器不会等待足够长的时间来报告完成情况。

我遇到了HostingEnvironment.QueueBackgroundWorkItem并认为可能有效,除非它看起来像当前的HttpContext不可用。我认为这可能会干扰CMS API,但我还计划使用会话状态作为我的标志来指示任务何时完成。

我看过网页,比如旅游网站或SSRS网页界面,它会显示一个轮询页面,同时会执行一些长时间运行的处理。我不需要任何花哨或错综复杂的目的,我只需要避免超时。我是否在QueueBackgroundWorkItem的错误轨道上?如果没有,我怎么知道任务何时完成?

3 个答案:

答案 0 :(得分:1)

您可能想要使用以下其中一项......

  • Application State - 要存储处理状态,如果您的应用程序位于单个服务器上,而不是多个系统,则这只是一个选项。您将要在另一个线程中启动处理,该线程在完成后更新应用程序状态,因此它不会阻止启动请求。
  • SignalR - 您可以使用消息启动该过程,并在完成后返回消息。 (再次使用单独的线程/线程池)

其他选项包括Message Queue系统,它允许在故障单完成时进行跟踪,或者自己使用数据库进行跟踪。

答案 1 :(得分:1)

您可以使用HangFire之类的工具来启动和执行服务器中的后台任务并跟踪它。当任务完成时,它可以与SignalR(如@ Tracker1建议)一起用于向客户端发送通知。

答案 2 :(得分:0)

我解决了HttpRequest问题上的CMS API依赖关系,所以我不必再担心了。我最终使用HostingEnvironment.QueueBackgroundWorkItem并将其传递给当前的HttpSessionState。后台线程Action启动时,它会在会话中放置一个对象,以指示任务是否仍在运行,是否有错误或是否已成功完成。同时,该页面使用jQuery AJAX请求轮询一个ASP.NET页面方法,该方法从会话中读取该状态对象。出于此管理页面的简单目的,它运行良好。由于我们正在使用会话状态服务器,因此它也应该在服务器场中运行。