C#定时任务之FluentScheduler

Deadly 提交于 2021-01-18 18:59:27

一、业务需求

平台首页,有几个指标统计,产品不要求实时性,觉得一天更新一次可以接受。

最后决定用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

https://www.jianshu.com/p/25d55249dce7

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!