zoukankan      html  css  js  c++  java
  • C#定时任务之FluentScheduler

    一、业务需求

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

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

  • 相关阅读:
    从迷宫终点出发——Leo鉴书36
    OCP-1Z0-053-V13.02-238题
    OCP-1Z0-053-V13.02-233题
    OCP-1Z0-053-V13.02-232题
    OCP-1Z0-053-V13.02-228题
    OCP-1Z0-053-V13.02-226题
    OCP-1Z0-053-V13.02-225题
    OCP-1Z0-053-V13.02-221题
    OCP-1Z0-053-V13.02-219题
    OCP-1Z0-053-V13.02-216题
  • 原文地址:https://www.cnblogs.com/zhuanjiao/p/12041071.html
Copyright © 2011-2022 走看看