简体   繁体   English

在C#.NET Web应用程序中每天安排任务的正确方法

[英]Proper way to schedule a task daily in C# .NET web application

I have an ASP.NET MVC app that let users store media like videos and photos. 我有一个ASP.NET MVC应用程序,可让用户存储视频和照片等媒体。

The application also lets the users delete those media stored in the server. 该应用程序还允许用户删除存储在服务器中的那些媒体。 To do so i want to implement a "two steps" process in which first (when the media is selected to be deleted), the media entry at the database will get a timestamp that indicates that the entry has to be deleted in some time (a month for example); 为此,我想实现一个“两步”过程,在此过程中,首先(当选择要删除媒体时),数据库中的媒体条目将获得一个时间戳,指示该条目必须在一段时间内删除(例如一个月); if that timestamp is not removed in that time, there should be a scheduled method that executes daily and checks if a media entry has a timestamp old enough to be deleted. 如果没有在那个时间删除该时间戳,则应该有一个计划的方法每天执行一次,并检查媒体条目是否具有足以删除的时间戳。

My question is about the scheduler: I've readed that there are some frameworks like FluentScheduler or Quartz.NET to implement that kind of jobs. 我的问题是关于调度程序的:我已经读过一些诸如FluentScheduler或Quartz.NET的框架来实现这种作业。 Since the application is a web application deployed in IIS, i'm afraid to not use the proper way, framework or method to implement it. 由于该应用程序是在IIS中部署的Web应用程序,因此恐怕没有使用正确的方法,框架或方法来实现它。 Since IIS could shutdown my application at any time and since the scheduled method would execute writes to DB and to the IO File system to delete the db entries and the physical files, it is vital to me that the method executes completely or does not execute at all, to keep the db consistent with the files stored at hd. 由于IIS可以随时关闭我的应用程序,并且由于计划的方法将执行对DB和IO File系统的写入操作以删除db条目和物理文件,因此对我来说至关重要的是,该方法完全执行或不在以下位置执行所有,以保持数据库与高清存储的文件一致。

My first bet is for FluentScheduler, but i need to know if using frameworks like that is the best solution. 我的第一个赌注是针对FluentScheduler,但我需要知道使用这样的框架是否是最佳解决方案。

I know that this kind of questions are not welcome in StackOverflow. 我知道在StackOverflow中不欢迎此类问题。 It is not an opinion question, i just want to read the solutions and select the one that best fits my requirements. 这不是一个意见问题,我只想阅读解决方案并选择最适合我的要求的解决方案。

Here is some kind of pseudo-code of what would be inside the scheduled method: 这是调度方法内部的某种伪代码:

using(ViewMediaDBUnitOfWork uw = new ViewMediaDBUnitOfWork())
        {
            var today = DateTime.Now.Date;

            List<Media> mediaToDelete = uw.MediaRepository.Get(m => (m.ToDelete - today).value.Days > 30);
            mediaToDelete.ForEach(m =>
            {
                try
                {
                    //Deletes from DB
                    uw.MediaRepository.Delete(m);
                    //Deletes the file
                    File.Delete(m.Path);
                    //If everything is ok, savechanges
                    uw.MediaRepository.SaveChanges();
                }
                catch(Exception e)
                {
                    LogManager.GetCurrentClassLogger().Error("Error deleting. " + m.Path, e);
                }                    
            });
        }

If you are going to schedule a task, at a minimum you'd want to at least do it within the context of HostingEnvironment.QueueBackgroundWorkItem . 如果要计划任务,则至少要至少在HostingEnvironment.QueueBackgroundWorkItem的上下文中执行该任务 This will register your work with the ASP.NET runtime. 这将在ASP.NET运行时中注册您的工作。 Though there are caveats. 尽管有一些警告。 When ASP.NET recycles for whatever reason, it will notify the background work (by setting a CancellationToken) and it will then wait up to a specified period of time (I think 30 seconds) for the work to complete. 当ASP.NET出于任何原因回收时,它将通知后台工作(通过设置CancellationToken),然后将等待指定的时间段(我认为是30秒)以完成工作。 If the background work doesn't complete in that time frame, the work will be gone. 如果后台工作在该时间段内未完成,则工作将消失。

FluentScheduler and Quartz are good frameworks, but you should avoid scheduling work within the context of your ASP.NET application if you can avoid it (for the reasons stated above). FluentScheduler和Quartz是很好的框架,但是如果可以避免,则应避免在ASP.NET应用程序的上下文中安排工作(由于上述原因)。 You could create a service that that uses these frameworks to schedule jobs / recurring tasks outside of your application. 您可以创建一个服务,该服务使用这些框架在应用程序外部安排作业/重复任务。

However, a more robust choice is to use a technology / framework like Hangfire which works in conjunction with some kind of reliable storage such as SQL Server, Redis, or MSMQ. 但是,更健壮的选择是使用类似于Hangfire的技术/框架,该技术/框架可与某种可靠的存储(例如SQL Server,Redis或MSMQ)结合使用。

Hangfire is an open-source framework that helps you to create, process and manage your background jobs, ie operations you don't want to put in your request processing pipeline . Hangfire是一个开源框架,可帮助您创建,处理和管理后台作业, 即您不想放入请求处理管道中的操作

It sounds like you would be better off creating a separate service to handle the deletion of the timestamped records rather than trying to bundle it in to your existing application. 听起来您最好创建一个单独的服务来处理带时间戳的记录,而不要尝试将其捆绑到现有应用程序中。

As one very quick solution, It would take about 10 minutes to create a Powershell script that would run an SQL query, deleting data where the TimeStamp > x date. 作为一种非常快速的解决方案,创建一个Powershell脚本大约需要10分钟, 该脚本将运行SQL查询,并删除TimeStamp> x日期的数据。

You could then schedule this script to run every day. 然后,您可以安排该脚本每天运行。 It would be much more reliable than hoping a IIS worker pool thread would still be running. 这比希望IIS工作池线程仍在运行要可靠得多。

There are a few other ways also, such as SSIS but that might be more complicated than what you need. 还有其他一些方法,例如SSIS,但可能比您需要的方法更复杂。

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

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