C# 在.NET中执行长时间运行任务的方法

C# 在.NET中执行长时间运行任务的方法,c#,asp.net,asp.net-mvc,iis,service,C#,Asp.net,Asp.net Mvc,Iis,Service,我正在开发一个相当大的网站,其中包括一个客户群和计费计划。每月计费应自动进行(但是,根据业务规则,员工应每月手动单击按钮启动该流程),客户数量在3000-5000之间。在每一张发票上,价格线都应该基于相当多的参数甚至来自Web服务的外部数据进行计算 以上内容肯定是一项(非常)长时间运行的任务,由于应用程序是在IIS上运行的ASP.NET MVC网站,我不希望进程在IIS上自己的线程中运行。我担心的是,如果IIS/Web服务器发生任何事情,计费计算过程也会停止,至少可以说这是至关重要的 因此,我正

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

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

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


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

看起来是信号机的一个很好的解决方案:

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

只要您有账单运行的“标题”记录,您就可以轻松存储您当前使用的记录以及运行是否已完成。无论您是作为windows服务运行还是作为IIS中的线程运行,这将始终是一个考虑因素-有人可以随时关闭计算机

信号员会允许你

  • 作为后台任务启动运行
  • 轻松地将进度传递回UI
  • 允许您从UI停止运行
  • 如果用户关闭浏览器,则重新连接到正在运行的运行
  • 收听“已完成”事件等
  • 允许从多个客户端查看进度

如果只是一个或两个长时间运行的任务,请简化生活,并使用Windows任务调度程序和C#console应用程序解决此问题。如果您有权访问控制台/RDP,则创建一个计划任务,该任务将:

  • 定期执行,比如每五分钟检查一次要做的工作

  • 如果只是运行一个任务,那么在您的web前端,当用户想要启动您的计费运行时,web前端会翻转数据库中的状态标志

  • 计划任务通知您的状态标志已翻转到“运行模式”

  • 运行计费代码

  • 完成后,重置“运行模式”

  • 先决条件-

  • 计算出您的计费运行代码,以便可以从控制台exe调用它

  • 确保将上述计划任务配置为在任务已运行的情况下不启动新实例(默认设置,但请仔细检查“创建任务”对话框中的设置选项卡)

  • 添加一些日志记录,以便了解任务的完成/进度

  • 其他解决方案注意事项:

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

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


    几年前,我实际上有一个要求做类似的事情。这是为了处理每月的会费。我做这件事的方法很简单。首先,在数据库中添加一个类似于以下内容的表:

    --------------------------------------
    |Monthly Processing Table            |
    |------------------------------------|
    |MonthlyProcessorId       int     PK |
    |ProcessMonth             int        |
    |ProcessYear              int        |
    |HasBeenProcessed         bool       |
    |CanBeProcessed           bool       |
    |ProcessDate              DateTime   |
    |------------------------------------|
    
    当然,您可以根据需要添加其他字段。这只是一个示范

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

  • 获取当前月份和年份(
    DateTime.Now
  • 在每月处理表中搜索与
    ProcessMonth
    等于
    DateTime.Now.Month
    ProcessYear
    等于
    DateTime.Now.Year
    匹配的行
  • 如果返回了任何行,则检查该行并查看
    HasBeenProcessed
    是否为
    true
    ProcessDate
    ,以查看何时将此操作报告给用户,然后您就完成了。这是一个重要的步骤,因为如果行是返回,并且
    已被处理
    true
    ,则每月的会费可能已经在本月内运行,您不希望向人员收取双倍的费用。因此,如果
    HasBeenProcessed
    为true,请不要跳过此步骤并停止此处的程序执行逻辑
  • 如果没有返回行,则创建新行。将
    ProcessMonth
    设置为
    DateTime.Now.Month
    ProcessYear
    设置为
    DateTime.Now.Year
    。将
    CanBeProcessed
    设置为
    true
    并将
    HasBeenProcessed
    设置为
    false
  • 拼图的最后一块是让Windows服务位于后台,定期从数据库中提取所有行,其中
    已处理的
    等于
    false
    可处理的
    等于
    true

    如果返回了任何行,则只需处理它们,然后在处理它们之后,将
    ProcessDate
    设置为
    DateTime。现在
    并将
    HasBeenProcessed
    设置为
    true
    。最后,您的服务只是回到定期检查。当我说“定期检查”时,我指的可能是每天检查一次,甚至可能是每周检查一次,这取决于您的要求。此服务不应以任何方式使您的SQL server陷入困境

    您可以使用一个控制台应用程序来代替Windows服务,该应用程序计划与Windows调度器一起运行。我优先