在.net中执行长时间运行任务的方法

本文关键字:运行 任务 方法 长时间 执行长 net 执行 | 更新日期: 2023-09-27 17:54:10

我正在开发一个相当大的网站,其中包括客户群和计费计划。每月的账单应该自动发生(但是,根据业务规则,员工应该手动单击按钮以启动每个月的流程),并且客户数量在3000 - 5000之间。在每张发票上,价格线都应该基于相当多的参数,甚至是来自web服务的外部数据来计算。

以上肯定是一个(非常)长时间运行的任务,因为应用程序是ASP。. NET MVC网站在IIS上运行,我不希望进程在IIS上运行在它自己的线程中。我担心的是,如果IIS/web服务器发生任何事情,计费计算过程也会停止,这将是至关重要的,至少可以说。

因此,我正在寻找替代方案,并阅读了关于为这样的任务创建Windows服务的内容。是这条路吗?或者是否有其他更"现代"的方式来运行长流程?该过程必须能够从ASP启动。. NET MVC应用。

任何帮助/提示是非常感谢!:-)

在.net中执行长时间运行任务的方法

几年前我有一个类似的需求。这是用来处理每月会费的。我的做法很简单。首先,在数据库中添加一个表,如下所示:

--------------------------------------
|Monthly Processing Table            |
|------------------------------------|
|MonthlyProcessorId       int     PK |
|ProcessMonth             int        |
|ProcessYear              int        |
|HasBeenProcessed         bool       |
|CanBeProcessed           bool       |
|ProcessDate              DateTime   |
|------------------------------------|

当然,您可以添加其他您认为合适的字段。这只是一个示范。

接下来,创建包含按钮的网页,该按钮应该每月按下以开始处理。当按钮被点击时,它应该执行以下逻辑:

  1. 获取当前月份和年份(DateTime.Now)
  2. 在月处理表中查找符合ProcessMonth = DateTime.Now.MonthProcessYear = DateTime.Now.Year的行
  3. 如果有任何行返回,然后检查行并查看HasBeenProcessed是否为trueProcessDate,以查看何时并将此报告给用户并完成。这是一个重要的步骤,因为如果行是返回,HasBeenProcessedtrue,那么这个月的月费可能已经运行了,您不想向人们收取双倍费用。所以不要跳过这一步,如果HasBeenProcessed为真,就在这里停止程序执行逻辑!
  4. 如果没有返回行,则创建新行。设置ProcessMonth = DateTime.Now.Month, ProcessYear = DateTime.Now.Year
  5. 设置CanBeProcessedtrue, HasBeenProcessedfalse

最后一块拼图是有一个Windows服务,它位于后台,定期从数据库中提取HasBeenProcessed等于falseCanBeProcessed等于true的所有行。

如果返回任何行,则直接处理,处理后将ProcessDate设置为DateTime.Now,将HasBeenProcessed设置为true。最后,您的服务将返回定期检查。当我说"定期检查"时,我指的是可能一天一次,甚至可能一周一次,这取决于你的要求。这个服务不应该以任何方式使你的SQL服务器陷入困境。

代替Windows服务,你可以有一个控制台应用程序,计划与Windows调度程序一起运行。不过我更喜欢Windows Service的方式,因为它对我来说"感觉更合适"。

现在,如果你真的想要它,你可以把你的时间表时间和逻辑写在一个接口。这样你就可以重用这个Windows服务。

看起来像是SignalR的一个很好的解决方案:http://www.asp.net/signalr

通常,这是SQL存储过程/代理作业的理想情况,但如果您需要为每个账单调用外部web服务来收集所需的数据,则不是。

只要你有一个账单运行的"头"记录,你就可以很容易地存储你当前在哪个记录上以及运行是否已经完成。无论您是作为windows服务还是作为IIS中的线程运行,都将始终作为一个考虑因素-有人可以在任何时候关闭机器。

SignalR将允许您

  • 将运行作为后台任务启动
  • 很容易将进度传递回UI
  • 允许您从UI停止运行
  • 如果用户关闭浏览器,重新连接正在运行的程序
  • 监听'completed'事件等
  • 允许从多个客户端查看进度

如果它只是一个或两个长时间运行的任务,保持简单,用Windows任务调度程序和c#控制台应用程序来解决这个问题。如果你已经访问了控制台/RDP,那么创建一个计划任务,它将:

  1. 定期执行,例如每五分钟检查一次是否有工作要做。

  2. 如果它像运行一个任务一样简单,那么在你的web前端,当用户想要启动你的计费运行时,那么web前端在你的数据库中翻转一个状态标志。

  3. 计划任务通知您的状态标志已切换到"运行模式"

  4. 运行计费代码

  5. 完成后重置"运行模式"

先决条件——

  1. 将您的计费运行代码提取出来,以便可以从控制台exe调用。

  2. 确保前面提到的计划任务被配置为不启动一个新的实例,如果任务已经在运行(默认值,但在"创建任务"对话框中仔细检查设置选项卡)。

  3. 添加一些日志记录,这样你就知道任务已经完成了多少/进度

其他解决方案注意事项:

  • 长时间运行的IIS任务:您的web服务器不是为执行长时间运行的任务而设计的,例如批处理任务,这本质上是您的计费任务。

  • Windows Services:为什么要重新发明轮子,增加学习编写Windows服务的复杂性