【问题标题】:How to fire off and poll a windows service from asp.net page如何从 asp.net 页面启动和轮询 Windows 服务
【发布时间】:2012-11-02 01:41:07
【问题描述】:

客户想要一个asp.net 页面,该页面有一个按钮,可以从具有数百条记录的外部源触发数据库更新。这个过程需要很长时间。他还希望在流程运行时更新状态,例如“处理 1000 条记录中的 10 条”。在阅读各种文章时,我正在考虑将数据库更新代码放在 Windows 服务中。我以前从未使用过 Windows 服务,也找不到很多关于如何启动 Windows 服务并从 asp.net 页面轮询它的教程。我的问题是这是处理此过程的最佳方式吗?而且,有没有人有任何例子说明他们是如何做到这一点的?

【问题讨论】:

标签: asp.net windows-services long-polling long-running-processes


【解决方案1】:

有几种方法可以解决这个问题。

您说得对,在 Web 的工作进程中执行长时间运行的任务通常不会有好的结果:它会占用资源,应用程序池可能会被回收,等等。在我的大多数复杂项目中,我通常最终得到 4 个部分:数据库、一个包含我的模型的 DLL、一个作为 Windows 服务的“Worker”以及一个 ASP.NET 网站。

“Worker”是一个始终运行的 Windows 服务,它使用Quartz.net 执行计划任务,使用的模型与网站使用的模型相同。这些可能是在维护任何复杂的网站时似乎会突然出现的各种周期性任务:VacuumExpiredPickTicketsJobBackupAndFtpDatabaseJobSendBackorderReminderEmailsJob 等。

在 C# 中编写 Windows 服务并不难(Visual Studio 中有一个内置模板,但您几乎可以从 ServiceBase 继承,然后您就可以参加比赛了),以及像 TopShelf 这样的库部署它们更加容易。

剩下的就是从网站触发更新并将结果反馈给用户。这可以像您希望的那样简单或复杂。如果这需要扩展到大量用户,您可以使用MSMQ 之类的东西将更新命令排队到 Windows 服务,然后 Windows 服务会响应该队列。我的印象是,这可能有点矫枉过正。

对于少数用户,您可以覆盖服务的 OnCustomCommand(int command) 方法作为触发器。然后,您的网站将使用ServiceController 类的ExecuteCommand() 来启动该过程。您的网站和服务会同意表示“进行更新”的参数值,例如 142(因为历史原因,它必须是 128 到 255 之间的数字)。

至于将进度反馈给客户端,最简单的方法可能是让网页使用计时器和 AJAX 调用来轮询更新的进度数据。你可以喜欢WebSockets(我写这篇文章时最前沿的东西)和long polling这样的新东西,但定期轮询只适用于不需要扩展的东西。

希望这会有所帮助!

【讨论】:

  • 你是对的,MSMQ 是矫枉过正,定期轮询很好,但是......你如何从 asp.net 页面对 Windows 服务进行定期轮询?我知道如何使用 ajax 和计时器控件,但是我应该在 Windows 服务上调用什么来恢复状态?
  • 我考虑过 DB 方法,我只是想知道是否为每个产品击中 DB 900 次会是一个瓶颈。
【解决方案2】:

除了 Nicholas 的详尽回答之外,另一种选择是将后端进程部署为命令行脚本,并安排它们通过 Window 的内置任务调度程序运行,这在 Windows Server 2008+ 中得到了相当大的改进。或者您可以使用任何其他主机的任务调度程序应用程序。

我发现与标准 Windows 服务相比,命令行方法更容易让 MIS 员工理解和配置,以及迁移到新服务器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多