如何使用 mvc5 在 asp.net/C# 中制作预定进程

how to make scheduled process in asp.net/C# with mvc5

我有一个 MVC5 应用程序,它具有在订阅时事通讯后向用户发送电子邮件的功能。现在我需要向订阅到期日提前 1 个月 运行 的所有用户发送电子邮件。在这种情况下,我需要在 Web 服务器上的特定时间每天 运行 实施一个后台进程。我该怎么做?

谢谢

这实际上取决于您的要求,以及您是否希望此更新真正独立于服务器、Web 应用程序或与您的应用程序捆绑在一起。

我最近为 ASP.NET 找到了一个很棒的第三方库,名为 Hang Fire

看起来可以这么简单:

RecurringJob.AddOrUpdate(
    () => Console.WriteLine("Transparent!"), 
    Cron.Daily);

支持:

  • 延迟作业
  • 重复性任务
  • 自动重试
  • 它有一个很好的主题 Management/Reporting 界面

我打算将它用于一些我需要在 CRM 系统上 运行 的计划的批处理任务。还没有使用它的经验,但它似乎确实有一些很棒的功能,我想我已经看到它在 Stack Overflow 周围被推荐了几次!

有很多不同的方法可以满足您的需求(服务器上的计划任务是我无法想到的另一个方法)。这是一个不错的小包,可以让我将它与我的 Web 应用程序捆绑在一起。

就个人而言,我会创建一个单独的专用 Windows 服务来定期检查过期时间,然后调用代码发送电子邮件。

另一种方法是为 运行 任务创建一个简单的控制台应用程序,然后使用 Windows 任务计划程序调用它。

一种不太安全的方法是使用 ping 服务,定期访问带有混淆的 URL 处理电子邮件的页面。

一篇略显陈旧但相关的博客 post,详细介绍了 .net 站点中经常性后台任务的问题 can be read here

您可以创建一个 Windows 服务来为您服务。 你应该遵循这个 tutorial。 您可以将 date/time 存储在项目 web.config/app.config 上,当您希望执行服务时。当服务执行时,您验证时间并调用将执行您想要的操作的通用函数。按照这个例子:

public partial class Service1 : ServiceBase
{
    YourServiceClass service;
    private Timer serviceTimer;

    public Service1()
    {
        InitializeComponent();
        service = new YourServiceClass();
    }

    protected override void OnStart(string[] args)
    {
        TimerCallback timerDelegate = new TimerCallback(service.GetData); // You should add this function to your class. You have an example below

        string time = System.Configuration.ConfigurationSettings.AppSettings["SceduleTime"];    // Gets time from app.config like 12:50
        string[] timeS = time.Split(':');

        DateTime DateIni = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(timeS[0]), Convert.ToInt32(timeS[1]), 0);

        TimeSpan diff = DateTime.Now - DateIni;
        if (diff.TotalSeconds < 0)
            diff = DateIni - DateTime.Now;
        else
            diff = DateIni.AddDays(1) - DateTime.Now;

        // create timer and attach our method delegate to it
        serviceTimer = new Timer(timerDelegate, service, diff, new TimeSpan(1, 0, 0, 0));
    }

    protected override void OnStop()
    {
        serviceTimer.Dispose();
    }
}

然后在您的 YourServiceClass class 上添加此函数:

public void GetData(object state){
    // Do something...
}

希望对您有所帮助!

我建议您使用 Quartz 库。您的流程应该独立于您的 Web 应用程序,因为 Web 应用程序会根据用户流量不时回收,这将触发 Application_End 事件,并在发送新请求后启动,这将触发 Application_Start所以您将无法正确管理您的日程安排开始和结束。