网页执行长任务不超时

Web page perform long task without timing out

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

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

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

我见过旅游网站或 SSRS 网络界面等页面在执行一些长时间 运行ning 处理时显示轮询页面。为此,我不需要任何花哨或复杂的东西,我只需要避免超时。我在 QueueBackgroundWorkItem 的轨道上走错了吗?如果没有,我怎么知道任务何时完成?

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

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

其他选项包括允许跟踪工单是否完整的消息队列系统,或者您自己使用数据库进行跟踪。

您可以使用 HangFire 之类的工具在您的服务器中启动和执行后台任务并对其进行跟踪。它可以与 SignalR 结合使用(如 @Tracker1 建议的那样),以便在任务完成时通知客户端。

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