简体   繁体   English

在ASP.NET MVC网站中运行重复任务

[英]Running a repeating task in an ASP.NET MVC website

I'm working on an ASP.NET MVC application where I need to keep updating a file in a time-interval. 我正在使用ASP.NET MVC应用程序,在该应用程序中,我需要在时间间隔内不断更新文件。 I will eventually be hosting this website on Windows Azure. 我最终将在Windows Azure上托管此网站。

I was just wondering if the approach mentioned in Phil Haack's post The Dangers of Implementing Recurring Background Tasks In ASP.NET is still the best approach or if I should look into creating a console app or so and use Azure Web Jobs to run it? 我只是在想,Phil Haack的帖子“在ASP.NET中实现重复执行后台任务的危险”中提到的方法是否仍然是最佳方法,还是我应该考虑创建一个控制台应用程序或使用Azure Web Jobs来运行它?

Any thoughts appreciated. 任何想法表示赞赏。

Thanks, Daniel 谢谢,丹尼尔

You can do something like this: 您可以执行以下操作:

    private void AddHourlyTask(string task)
    {

        DateTime expiration = DateTime.Now.AddHours(1);
        expiration = new DateTime(expiration.Year, expiration.Month, expiration.Day, expiration.Hour, expiration.Minute, expiration.Second, expiration.Kind);

        OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
        HttpRuntime.Cache.Insert(
            task,
            task,
            null,
            expiration,
            Cache.NoSlidingExpiration,
            CacheItemPriority.NotRemovable,
            OnCacheRemove);
    }

And then in a separate function: 然后在一个单独的函数中:

    public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
    {
        if (k == "HelloWorld")
        {
            Console.Write("Hello, World!");
            AddHourlyTask(k);
        }

This would go into your Application_Start() function as: 这将以以下方式进入您的Application_Start()函数:

AddHourlyTask("HelloWorld");

In order for this to work, you also need to add this somewhere in your class: 为了使它起作用,您还需要将其添加到班级中的某个位置:

private static CacheItemRemovedCallback OnCacheRemove = null;

The functions would all sit in your Global.asax.cs file 这些功能全部位于您的Global.asax.cs文件中

You might look at scheduling a simple console app, batch file, perl script, etc. with the windows task scheduler. 您可能会使用Windows任务计划程序来计划简单的控制台应用程序,批处理文件,Perl脚本等。 Depending on what it needs to do, it could be as simple as invoking a web method in your ASP.Net MVC web app. 根据需要执行的操作,就像在ASP.Net MVC Web应用程序中调用Web方法一样简单。

One option is looking into Quartz . 一种选择是研究Quartz

Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems. Quartz.NET是功能齐全的开源作业调度系统,可用于最小的应用程序到大型企业系统。

I asked a similar question on Programmers : How do I make my ASP.NET application take an action based on time? 我对程序员提出了类似的问题: 如何使我的ASP.NET应用程序根据时间采取措施?

Accepted Answer: 接受的答案:

A scheduled task triggered by either the Task Scheduler or Sql Server is the way to go here. 通过任务计划程序或Sql Server触发的计划任务就是这里的方法。 But if you really want to manage it within your webapp, you might want to look at something like Quartz.NET. 但是,如果您真的想在自己的Web应用程序中进行管理,则可能需要查看Quartz.NET之类的内容。 It will let you do scheduled tasks from the CLR. 它可以让您从CLR执行计划的任务。 Then your challenge is "how do I make sure the AppDomain stays up to run the tasks." 然后,您面临的挑战是“如何确保AppDomain保持运行任务的能力”。

Another way to do it as a scheduled task yet keep most of the "smarts" on the server is to make it a task that can be called over HTTP with some sort of authorization key. 另一种将其作为计划任务执行但又将大多数“智能”保留在服务器上的方法是使它成为可以通过HTTP使用某种授权密钥调用的任务。 This lets you write a relatively simple program to call it -- if not a simple shell script -- and to keep most of the complexity in the web app which is likely already capable of running the task. 这样,您就可以编写一个相对简单的程序来调用它(如果不是简单的Shell脚本),并将大多数复杂性保留在Web应用程序中,而该应用程序可能已经能够运行该任务。

Either way rolling your own task manager is really a path fraught with peril. 无论哪种方式,滚动您自己的任务管理器实际上都是一条充满危险的道路。

Scheduling tasks in an ASP.NET MVC project is possible using the Revalee open source project. 使用Revalee开源项目,可以在ASP.NET MVC项目中安排任务。

Revalee is a service that allows you to schedule web callbacks to your web application). Revalee是一项服务,可让您安排对Web应用程序的Web回调。 In your case, you would schedule a callback that would perform your desired action (ie, update a file). 在您的情况下,您将安排一个回调以执行所需的操作(即更新文件)。 Revalee works very well with tasks that are discrete transactional actions, like updating a database value or sending an automated email message (read: not long running). Revalee可以很好地处理作为离散事务操作的任务,例如更新数据库值或发送自动电子邮件消息(阅读:长期运行)。 The code to perform your action would all reside within your MVC app. 执行操作的代码都将驻留在您的MVC应用程序中。 When your application launches for the very first time, then you would schedule the first web callback. 当您的应用程序首次启动时,您将安排第一个Web回调。 When your application is called back to generate the report, then you would schedule the next callback. 当您的应用程序被调用回生成报告时,您将计划下一个回调。

To use Revalee, you would: 要使用Revalee,您需要:

  1. Install the Revalee Service, a Windows Service, on your server. 在服务器上安装Revalee服务(Windows服务)。 The Windows Service is available in the source code (which you would compile yourself) or in a precompiled version available at the Revalee website . Windows Service可以在源代码(您可以自己编译)中使用,也可以在Revalee网站上使用的预编译版本中使用。

  2. Use the MVC-specific Revalee client library in your Visual Studio project. 在Visual Studio项目中使用特定于MVC的Revalee客户端库。 (There is a non-MVC version too.) The client library is available in the source code (which, again, you would compile yourself) or in a precompiled version available via NuGet . (也有非MVC版本。)客户端库可以在源代码中使用(可以再次编译),也可以在通过NuGet获得的预编译版本中使用。

  3. You would register a future callback when your application launches for the very first time via the ScheduleHourlyCallback() method (this example is assuming that you need your action to run once per hour). 当您的应用程序首次通过ScheduleHourlyCallback()方法启动时,您将注册一个将来的回调(此示例假设您需要每小时执行一次操作)。

     private void ScheduleHourlyCallback() { // Schedule your callback for an hour from now var callbackTime = DateTimeOffset.Now.AddHours(1.0); // Your web app's Uri, including any query string parameters your app might need Uri callbackUrl = new Uri("http://yourwebapp.com/Callback/UpdateFile"); // Register the callback request with the Revalee service RevaleeRegistrar.ScheduleCallback(callbackTime, callbackUrl); } 
  4. When Revalee calls your application back, your app would perform whatever action you have coded it to do and your app schedules the next callback too (by calling the ScheduleHourlyCallback() method from within your controller's action). 当Revalee调用你的应用程序恢复,你的应用程序将执行任何动作已经编写它做的你的应用程序调度下一个回调太(通过调用ScheduleHourlyCallback()从控制器的操作中的方法)。

I hope this helps. 我希望这有帮助。

Note: The code example above uses a synchronous version of ScheduleCallback() , the Revalee client library also supports asynchronous calls à la: 注意:上面的代码示例使用ScheduleCallback()的同步版本,Revalee客户端库也支持异步调用,例如:

RevaleeRegistrar.ScheduleCallbackAsync(callbackTime, callbackUrl);

Disclaimer: I was one of the developers involved with the Revalee project. 免责声明:我是参与Revalee项目的开发人员之一。 To be clear, however, Revalee is free, open source software. 不过要明确一点,Revalee是免费的开源软件。 The source code is available on GitHub . 源代码可在GitHub上获得

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM