一、业务需求
平台首页,有几个指标统计,产品不要求实时性,觉得一天更新一次可以接受。
最后决定用FluentScheduler定时执行统计,redis缓存结果。
每天晚上1点进行定时任务统计,将统计结果缓存到redis中,业务接口直接从reids里拿统计数据。
二、开始撸代码
方式一:多个任务 + 不同时间段执行(这个没有实现,大家可以使用 一个从0点开始的分钟数,秒数等,自定义一个接口,根据规则去调用Schedule中的方法)
using System;
using System.Linq;
using System.Threading.Tasks;
using FluentScheduler;
namespace Common
{
// 自己定义了一个接口,目前只有一个方法,大家可以根据自己的需求添加接口,比如定义一个执行任务的时间接口等
public interface IScheduleTask
{
void Execute();
}
public class ScheduleTask : Registry
{
public ScheduleTask()
{
// 获取已加载到此应用程序域的执行上下文中的程序集(因为有延迟加载机制,
// 未加载到应用程序域的时候会报错,一般初始化的时候可能会再现问题)
// var types = AppDomain.CurrentDomain.GetAssemblies()
// .SelectMany(a => a.GetTypes()
// .Where(t => t.GetInterfaces()
// .Contains(typeof(IScheduleTask))))
// .ToArray();
var types = Assembly.GetAssembly(typeof(IScheduleTask)).GetTypes()
.Where(t => t.GetInterfaces().Contains(typeof(IScheduleTask))).ToArray();
foreach (Type type in types)
{
IScheduleTask obj = (IScheduleTask)Activator.CreateInstance(type);
Task.Run(() =>
{
//Schedule(() => obj.Execute()).ToRunNow().AndEvery(5).Seconds();// 每5秒执行一次
Schedule(() => obj.Execute()).ToRunEvery(1).Days().At(1, 0);// 每天晚上1点执行
});
}
}
}
public class FirstJob : IScheduleTask
{
public void Execute()
{
new RedisHelper().StringSet($"FirstJob{ Guid.NewGuid().ToString()}", "FirstJob执行");// 模拟业务统计一
}
}
public class SecondJob : IScheduleTask
{
public void Execute()
{
new RedisHelper().StringSet($"SecondJob{ Guid.NewGuid().ToString()}", "SecondJob执行");// 模拟业务统计二
}
}
}
Application_Start 方法添加 JobManager.Initialize(new ScheduleTask());
方式二:
using System; namespace Test { public class ThreeJob { public void Execute() { new RedisHelper().StringSet($"ThreeJob{ Guid.NewGuid().ToString()}", "ThreeJob执行");// 模拟业务统计三 } } }
Application_Start 方法添加 JobManager.AddJob(() => new ThreeJob().Execute(), t =>{t.ToRunNow().AndEvery(10).Seconds();});
方式三:实现IJob接口中的Execute方法
using System; using System.Linq; using System.Threading.Tasks; using FluentScheduler; namespace Test2 { public class ScheduleTask : Registry { public ScheduleTask() { //第二种调用业务方法: Schedule<FourJob>().ToRunNow().AndEvery(5).Seconds(); } } public class FourJob : IJob { public void Execute() { new RedisHelper().StringSet($"FourJob{ Guid.NewGuid().ToString()}", "FourJob执行");// 模拟业务统计四 } } }
Application_Start 方法添加 JobManager.Initialize(new ScheduleTask());
注意: 一般的程序池没有经过特殊设置,一定闲置时间后,程序池会自动回收,导致定时任务不执行;解决办法就是预加载,程序池回收后,模拟一次请求,进行初始化。
设置办法可以参照: https://blog.csdn.net/y1535623813/article/details/76534614