如何在Asp.net MVC中每隔24小时执行一次方法

11

我在MVC中有一个方法,类似于:

 public void Sendmails()
 {
     //sending mails for every 24 hours.
 }

我能否安排上述方法每24小时执行一次。 我知道我们可以使用SQL Server代理和Windows任务计划程序设置计划。 但由于某些问题,我只想执行当前的dll,这在MVC中可行吗?


你可能想要查看这个问题:https://dev59.com/52cs5IYBdhLWcg3wVyal - Smeegs
1
由于一些问题。什么问题? - ken2k
6个回答

19
可能吗?或许通过调用任务和后台线程进行一些黑客攻击是可能的。可靠吗?根本不可靠。
Web应用程序本质上是一个请求-响应系统。应用程序接收请求,执行其逻辑并返回响应。在此之外,它处于空闲状态。如果 Web 服务器想要使用或释放该内存,则完全可以将其从内存中卸载。
要定期运行某些东西而无需用户交互(即没有请求来启动它),Web 应用程序并非您所需。相反,您要寻找 Windows 服务或可能是简单的控制台应用程序,由主机系统的调度软件(Windows 任务计划程序、cron 等)定期运行。
这些应用程序当然可以共享代码。它们可以在同一解决方案中,并引用相同的类库。事实上,代码的应用层应尽可能轻薄,所有有意义的代码都应位于共享的业务逻辑程序集中。那么任何应用程序(Web 应用程序、Windows 服务、控制台应用程序等)都可以简单地引用这些共享程序集并调用相同的逻辑。
此外,多个正在运行的应用程序也可以轻松共享相同的数据。它们可以同时连接到同一数据库(当然要使用共享数据访问逻辑),并且本质上是中央逻辑的相同表示形式,这些逻辑恰好被单独的应用程序实例调用。

2
+1,解释得很清楚。也许值得补充的是,在ASP.Net应用程序和计划的应用程序/服务之间进行通信的方式有很多种(IPC):数据库、MSMQ等。 - ken2k

8

众所周知,在您的.NET Web应用程序中执行长时间运行的后台进程不是一个好的实践,因为会影响可靠性等方面。

您可以创建一个外部触发器,每24小时调用您的MVC操作方法。因此,您每24小时执行一次代码。有多种方法和服务可用于此,我已经使用了不同的服务。或者,如果您不想使用第三方服务,则可以自己创建。

例如,您可以使用pingdom.com的免费帐户来每<输入时间>周期调用特定的URL。因此,在pingdom中,您可以输入指向MVC操作的URL。

http://domain/controller/action

每24小时都会被调用,您的代码将按计划运行。
更新:最近我一直在使用 Azure 计划程序,它是专为这种场景构建的。 https://azure.microsoft.com/en-us/services/scheduler/

1
为什么要创建hack-y解决方案,当没有必要时呢?如果在24小时触发器设置的时间周围pingdom崩溃了怎么办? - Shiva
1
哈哈,我用nodeping.com做了完全相同的事情,但现在我知道QueueBackgroundWorkItem和Hangfire了...但是这个hack已经运行了三年,每3分钟就像魅力一样(99%+)。总有一天我会把它做对。当它不能及时完成时,nodeping会给我发送页面和电子邮件。:D 它只是一个惊人的“在10分钟内让它工作”的hack,从未被重新审视过。 - Hunter-Orionnoir

6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace Proposal_Sln
{
public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        System.Timers.Timer timer = new System.Timers.Timer();
        timer.Interval = 1000;
        timer.Elapsed+=timer_Elapsed;
        timer.Start();
    }

    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Models.Proposal_DBEntities DB = new Models.Proposal_DBEntities();
        Models.tbl_Year Y = new Models.tbl_Year();
        Y.YearName = "13" + DateTime.Now.Second.ToString();
        DB.tbl_Year.Add(Y);
        DB.SaveChanges();
    }
 }
}

它的工作表现不错。


4
这似乎是使用Revalee的绝佳用例。Revalee是一个开源项目,旨在处理这种类型的情况。它使用Windows Service管理任务持久性和调度,但利用Web应用程序处理处理工作。在您的情况下,您将通过Service每24小时调用一次SendEmail操作。
以下是使用Revalee的Web应用程序的工作流程: Revalee Workflow (来源:sageanalytic.com) 免责声明:我是参与Revalee项目开发的开发人员之一。然而,要明确的是,Revalee是免费、开源软件。源代码可在GitHub上获取。

我们需要在单独的系统操作系统中安装Revalee服务器并作为服务器运行吗?如果是这样,我们就无法托管此类服务了吗? - Developer
@sanjay:Revalee服务可以安装在任何Windows服务器上,包括Web托管服务器。我们曾经遇到过这样的情况,即用户无法控制Web服务器,但可以控制另一台服务器(如电子邮件服务器),因此能够成功地在该“其他”服务器上使用Revalee。 - László Koller
但是我们有其他更好的选择,比如Windows中的任务计划程序,具有相同的功能,而无需任何复杂的代码,有什么区别吗?我需要它在托管的网站本身运行,而不需要任何Windows存在。 - Developer

1
我同意@David的观点,将后台任务运行在Web应用程序中本质上是不可靠的,但也有一些情况下使用它是有意义的。我建议先阅读这篇优秀的文章:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
在.NET 4.5.2中,可以利用HostingEnvironment,如此优美地解释了这篇文章:http://blog.mariusschulz.com/2014/05/07/scheduling-background-jobs-from-an-asp-net-application-in-net-4-5-2。引用该文章的话,“HostingEnvironment.QueueBackgroundWorkItem方法允许您调度小型后台工作项。ASP.NET跟踪这些项,并防止IIS突然终止工作进程,直到所有后台工作项都完成。”
但再次强调,这不是一个好的做法,如果使用,应该明智地使用。

1
这些链接讨论如何运行任务,但不是定期(即每24小时一次)任务。 - ChrisW

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接