手机版

在AspNet内核上实现网络定时任务

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

作为一个后端程序狗,项目实践中经常会遇到调度任务的工作,最简单的思路就是利用Windows scheduled tasks//wndows service programs/Crontab programs等主机方法在主机上部署调度任务程序/脚本。

但是,在许多情况下,如果您使用的是共享主机或受控主机,未经许可,不允许安装exe程序和Windows服务程序。

代码a会想到在web程序中做定时任务。目前,有两个方向:

的主机服务。AspNetCore是一个轻量级的后台服务,需要定时器来完成定时任务。旧的Quartz.Net组件支持复杂而灵活的调度、ADO/RAM作业任务存储、集群、监控和插件。这里,我们的项目使用一个稍微复杂的Quartz.net来实现网页计时任务。

项目背景

最近,我们需要做一个计数程序:使用redis计数,并设置每天累积的数据每小时持久化到关系数据库sqlite中。

添加Quartz.Net nu get依赖包:包引用包括=' quartz '版本=' 3.0.6'/

1.定义计划任务的内容:作业2。设置触发条件:触发3。将Quartz.Net集成到AspNet核心头脑风暴中

IScheduler类封装了上述后台需要完成的第一个 Job,SimpleJobFactory定义了生成指定Job任务的过程,是利用反射机制调用无参数构造函数构造的作业实例。以下是源代码:

//- 选自石英。简单,简单的工厂类-使用系统;使用石英。日志记录;使用石英Spi .使用石英Util .名称空间石英.简单{///总结////Quartz使用的默认JobFactory简单地调用///参见cref='ObjectUtils .作业类上的实例化类型{ T }/.////摘要///另请参见cref=' IJobFactory '////另请参见cref=' properties settingjobfactory '///AuthorJames House/author///AuthorMarko Lahma(.NET)/作者公共类SimpleJobFactory : IJobFactory {私有静态只读ILog log=LogProvider .GetLogger(类型为(SimpleJobFactory));///摘要///在触发触发器时由调度程序调用,以便///生成一个请参见cref='IJob' /实例,在该实例上调用执行.////摘要////备注////这种方法抛出异常应该是极其罕见的——///基本上只有完全没有办法实例化///并准备执行职位的情况。当抛出异常时,///调度程序会将与作业相关联的所有触发器移动到///请参见cref='TriggerState .错误/状态,这将需要人工///干预(例如,在修复了导致实例化作业问题的任何///配置问题后,应用程序重新启动)。////备注///param名称='bundle '可从中获取请参见cref='IJobDetail'////以及与触发器触发相关的其他信息的TriggerFiredBundle ./param///param name=' scheduler '/param///返回新实例化的作业/返回///如果实例化作业时出现问题,将引发计划例外./抛出公共虚拟IJob新作业(TriggerFiredBundle包,ischidoler调度程序){ IJobDetail jobDetail=bundle .JobDetail类型作业类型=作业详细信息.作业类型尝试{ if (log .IsDebugEnabled()) { log .调试($)正在生成作业" { jobDetail } "的实例。键"{ 0 }",类={jobType .全名} ');}返回对象.实例化作业类型(JobType);} catch(异常e){ schedule exception se=new schedule exception($)实例化类" "工作详细信息时出现问题JobType。FullName}“”,e);扔se;} }///摘要////允许作业工厂在需要时销毁/清理作业。///使用SimpleJobFactory时无操作////摘要公共虚拟void返回作业(IJob作业){ var一次性=作为IDisposable的作业一次性的?dispose();} }}//- 节选自石英。对象类-公共静态测试实例化的对象(类型){ if(类型==null){ 0抛出新的ArgumentNullException(类型的名称),'无法实例化null’);} ConstructorInfo ci=type .GetConstructor(类型empty types);如果(ci==null){ 0引发新的ArgumentException(“”无法实例化没有空构造函数的类型,请键入。名称);}返回(T) ci .调用(新对象[0]);}很多时候,定义的职位任务依赖了其他组件,这时默认的SimpleJobFactory不可用,需要考虑将职位任务作为依赖注入组件,加入依赖注入容器。

关键思路:

.IScheduler开放了JobFactory属性,便于你控制职位任务的实例化方式;

对于那些希望应用程序通过某种特殊机制产生作业实例的人来说,作业工厂可能是有用的,比如给依赖注入机会AspNet .核心的服务架构是以依赖注入为基础的,利用进程核心已有的依赖注入容器构造函数管理职位服务的创建过程。

编码实践

定义职位内容:

//- 每小时将存储数据持久化到sqlite,每日凌晨跳针,持久化昨天全天数据-公共类usagecountryncjob : Ijob { private readonly eqid context _ context;private readonly IDatabase _ redis db 1;私有只读ILogger _ logger public usagecounteryncjob(EqidDbContext上下文,RedisDatabase redisCache,ILoggerFactory logger工厂){ _ context=context_ redis db 1=redis缓存[1];_logger=loggerFactory .createlogeragecounteryncjob();}公共异步任务执行(IJobExecutionContext上下文){ //触发时间在凌晨,则同步昨天的计数var _day=DateTime .现在。to字符串(' yyyyMMdd ');如果(上下文FireTimeUtc。本地日期时间。小时==0)_天=日期时间.现在。添加日期(-1)。ToString(' yyyyMMdd ');等待SyncRedisCounter(_ day);_记录器.登录信息('[usagecountryncjob]已执行计划作业');} .}注册职位和触发器:

命名空间EqidManager{使用iocontainer=IserviceProvider//石英。网启动后注册工作和触发公共类QuartzStartup { public is diodier _ scheduler { get;设置;}私有只读ILogger _ logger私有只读IJobFactory iojobfactoryppublic QuartzStartup(iocontainer iocontainer,ILoggerFactory logger factory){ _ logger=logger factory .createloger quartzstartup();IOCjobfactory=new IOCjobfactory(IOCcontainer);var schedulerFactory=new StdSchedulerFactory();_调度程序=调度工厂.GetScheduler().结果;_调度程序JobFactory=IOCjobfactory } public void Start(){ _ logger .登录信息('计划在应用程序启动时加载作业');_调度程序。开始()。wait();var usagecounteryncjob=作业生成器.CreateUsageCounterSyncJob().带IDentity(' UsageCountyncJob ').build();var usagecounteryncjumbrigger=TriggerBuilder .创建()。带有标识(' usagecountersyncron ').StartNow() //每隔一小时同步一次. WithCronSchedule('0 0 * * *?')//秒、分、小时、月、日、周、年(可选字段)。build();_调度程序ScheduleJob(usagecounteryncjob,UsageCounterSyncJobTrigger).wait();_调度程序触发作业(新JobKey(' usagecounteryncjob ');} public void Stop(){ if(_ scheduler==null){ return;} if (_scheduler .关机(waitForJobsToComplete: true).wait(30000))_ scheduler=null;else { } _logger .日志关键("在应用程序停止时计划作业上载");} } ///summary ///IOCJobFactory:实现在计时器触发的时候注入生成对应的职位组件////摘要公共类iojobfactory : Ijobfactory { protected readonly iocontainer;公共IOCJobFactory(IOCContainer容器){容器=容器}//在触发器触发时由调度程序调用,以便产生//一个石英.要在其上调用执行的工作实例。公共IJob NewJob(TriggerFiredBundle包,ischidiode er调度程序){返回容器GetService(捆绑包工作细节。JobType)作为IJob} //如果需要,允许作业工厂销毁/清理作业公共void ReturnJob(IJob作业){ } }}结合进程核心注入组件;绑定石英。网

//- 截取自启动文件-.服务addtransientusagecounteryncjob();//这里使用瞬时依赖注入服务AddSingletonQuartzStartup();//绑定石英网络公共空间配置(应用程序构建器应用程序,微软AspNetCore。主持。iapplicationlifetime lifetime,ILoggerFactory logger factory){ var quartz=app .应用服务。GetRequiredServiceQuartzStartup();一辈子。应用开始。注册(石英。开始);一辈子。应用程序寄存器(石英。停止);}附:IIS网站低频访问导致工作进程进入闲置状态的解决办法

(同移民检查员移民检查)为网站默认设定了20min闲置超时时间:20分钟内没有处理请求、也没有收到新的请求,工作进程就进入闲置状态。

IIS上的低频web访问将导致工作进程关闭,此时应用程序池将被回收,Timer等线程资源将被销毁;当工作流程重新运行时,计时器可能会重新生成以生效,但我们设置的计划作业可能无法按要求正确执行。

因此,为了在IIS网站上实现低频网页访问下的定时任务:

设置idle time out=0;同时,设置应用程序池-正在回收-取消选中回收条件

版权声明:在AspNet内核上实现网络定时任务是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。