用C#每天安排任务的正确方式.NET web应用程序

本文关键字:方式 NET web 应用程序 每天 任务 | 更新日期: 2023-09-27 17:57:25

我有一个ASP。NET MVC应用程序,允许用户存储视频和照片等媒体。

该应用程序还允许用户删除存储在服务器中的媒体。为此,我想实现一个"两步"过程,其中首先(当选择删除媒体时),数据库中的媒体条目将获得一个时间戳,指示该条目必须在某个时间(例如一个月)内删除;如果当时没有删除该时间戳,那么应该有一个每天执行的调度方法,检查媒体条目的时间戳是否足够旧,可以删除。

我的问题是关于调度程序:我已经读到有一些框架,比如FluentScheduler或Quartz。NET来实现这种作业。由于该应用程序是部署在IIS中的web应用程序,我担心没有使用正确的方式、框架或方法来实现它。由于IIS可以随时关闭我的应用程序,并且由于计划的方法将执行对数据库和IO文件系统的写操作,以删除数据库条目和物理文件,对我来说至关重要的是,该方法完全执行或根本不执行,以保持db与存储在hd中的文件的一致性。

我的第一个赌注是FluentScheduler,但我需要知道使用这样的框架是否是最好的解决方案。

我知道这种问题在StackOverflow中是不受欢迎的。这不是一个意见问题,我只想阅读解决方案,并选择最符合我要求的解决方案。

以下是调度方法中的一些伪代码:

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);
                }                    
            });
        }

用C#每天安排任务的正确方式.NET web应用程序

如果要安排一项任务,至少需要在HostingEnvironment的上下文中进行。QueueBackgroundWorkItem。这将向ASP注册您的作品。NET运行时。尽管有一些警告。当ASP。NET无论出于何种原因回收,它都会通知后台工作(通过设置CancellationToken),然后等待指定的时间段(我认为是30秒)以完成工作。如果背景工作没有在这个时间框架内完成,那么这项工作就没有了。

FluentScheduler和Quartz是很好的框架,但您应该避免在ASP的上下文中安排工作。NET应用程序,如果您可以避免它(由于上述原因)。您可以创建一个使用这些框架在应用程序之外安排作业/重复任务的服务。

然而,一个更稳健的选择是使用像Hangfire这样的技术/框架,它与某种可靠的存储(如SQL Server、Redis或MSMQ)结合使用。

Hangfire是一个开源框架,可以帮助您创建、处理并管理您的后台工作,即您不想进行的操作在您的请求处理管道中

听起来,您最好创建一个单独的服务来处理时间戳记录的删除,而不是试图将其捆绑到现有的应用程序中。

作为一个非常快速的解决方案,创建一个运行SQL查询的Powershell脚本大约需要10分钟,删除TimeStamp>x日期处的数据。

然后,您可以将此脚本安排为每天运行。这将比希望IIS工作池线程仍在运行可靠得多。

还有一些其他方法,例如SSIS,但这可能比您需要的更复杂。