zoukankan      html  css  js  c++  java
  • 完全基于net core容器的超级轻量化的Quartz,支持类似net core mvc的过滤器,附过滤器实现源码

    开源地址

    https://github.com/1448376744/Quartz

    由于quartz.net对容器支持不够友好,而且配置复杂,看不懂,还不支持过滤器,只能自己动手写一个

    基本使用,每次执行任务时都会从容器解析一个新的任务实例以及依赖

    static async Task Main(string[] args)
    {
        //创建容器
        var services = new ServiceCollection();
        services.AddScoped<Logger>();
        services.AddQuartzFactory(b =>
        {
            //设置时区
            b.PerExecuteUtcTime = () => DateTime.UtcNow.AddHours(8);
            //添加任务
            b.AddTask<MyQuartzTask>("0/1 * * * * ?", typeof(MyQuartzTaskFilter), typeof(MyQuartzTaskFilter2));
        });
        //构建容器
        var provider = services.BuildServiceProvider();
        //从容器获取任务调度工厂
        var factory = provider.GetRequiredService<QuartzFactory>();
        //启动任务调度
        await factory.StartAsync();
    }

    定义一个任务

    public class MyQuartzTask : IQuartzTask
    {
        readonly Logger _logger = null;
        public MyQuartzTask(Logger logger)
        {
            _logger = logger;
        }
        public async Task ExecuteAsync(TaskExecutingContext context)
        {
            await Task.Run(() =>
            {
                Console.ForegroundColor = ConsoleColor.Green;
                _logger.Log($"[任务:1][时间:{DateTime.Now}][线程ID:{Thread.CurrentThread.ManagedThreadId}],执行目标任务");
                Console.ForegroundColor = ConsoleColor.White;
            });
        }
    }

    定义过滤器1

     public class MyQuartzTaskFilter : IQuartzTaskFilter
     {
         public async Task OnExecuteAsync(TaskExecutingContext context, QuartzTaskExecuteDelegate next)
         {           
             Console.WriteLine("[过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务");
             await next();
             Console.WriteLine("[过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务");
         }
     }

    定义过滤器2

    public class MyQuartzTaskFilter2 : IQuartzTaskFilter
    {
        public async Task OnExecuteAsync(TaskExecutingContext context, QuartzTaskExecuteDelegate next)
        {           
            Console.WriteLine("[过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务");
            await next();
            Console.WriteLine("[过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务");
        }
    }

    定义一个日志,用于测试依赖注入,支持scope级别

    public class Logger
    {
        public void Log(string message)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message);
            Console.ForegroundColor = ConsoleColor.White;
        }
    }

    跑起来,从执行结果虽然看不出是1秒一次,底层是基于线程池的任务排队进行的,由于控制台打印的延迟,导致Datetime.Now获得的时间不一定是一秒一次

    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [任务:1][时间:2020/4/4 14:15:05][线程ID:6],执行目标任务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务
    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务
    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [任务:1][时间:2020/4/4 14:15:06][线程ID:5],执行目标任务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务
    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务
    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 开启事务
    [任务:1][时间:2020/4/4 14:15:08][线程ID:6],执行目标任务
    [过滤器2][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务
    [过滤器1][线程ID:{Thread.CurrentThread.ManagedThreadId}] 关闭事务

    过滤器栈源码实现

    创建一个过滤器执行器,实现原理是递归

    /// <summary>
        /// 过滤器执行器
        /// </summary>
        public class QuartzFilterExecutor
        {
            /// <summary>
            /// 过滤器
            /// </summary>
            private Queue<IQuartzTaskFilter> _filters = new Queue<IQuartzTaskFilter>();
    
            /// <summary>
            /// 创建一个过滤器执行器
            /// </summary>
            /// <param name="filters"></param>
            public QuartzFilterExecutor(List<IQuartzTaskFilter> filters)
            {
                foreach (var item in filters)
                {
                    _filters.Enqueue(item);
                }
            }
    
            /// <summary>
            /// 执行过滤器栈
            /// </summary>
            /// <param name="next">任务执行器</param>
            /// <returns></returns>
            public Task Execute(Func<Task> next)
            {
                return Builder(next)();
            }
    
            /// <summary>
            /// 构建执行器栈,递归
            /// </summary>
            /// <param name="next">任务执行器</param>
            /// <returns></returns>
            private Func<Task> Builder(Func<Task> next)
            {
                if (_filters.Count > 0)
                {
                    var filter = _filters.Dequeue();
                    async Task current()
                    {
                        await filter.OnExecuteAsync(new TaskExecutingContext
                        {
    
                        }, new QuartzTaskExecuteDelegate(Builder(next)));
                    }
                    return current;
                }
                else
                {
                    return next;
                }
            }
        }

    过滤器接口

    /// <summary>
    /// 过滤器
    /// </summary>
    public interface IQuartzTaskFilter
    {
        /// <summary>
        /// 任务执行过滤
        /// </summary>
        /// <param name="context">任务执行上下文</param>
        /// <param name="next">任务委托</param>
        /// <returns></returns>
        Task OnExecuteAsync(TaskExecutingContext context, QuartzTaskExecuteDelegate next);
    }
    /// <summary>
    /// 任务执行委托
    /// </summary>
    /// <returns></returns>
    public delegate Task QuartzTaskExecuteDelegate();

    任务接口

    /// <summary>
    /// 任务
    /// </summary>
    public interface IQuartzTask
    {
        Task ExecuteAsync(TaskExecutingContext context);
    }

    跑起来

     static async Task Main(string[] args)
     {
         //创建任务级过滤器
         var task = new MyQuartzTask(new Logger());
         var filter1 = new MyQuartzTaskFilter();
         var filter2 = new MyQuartzTaskFilter();
         var executor = new QuartzFilterExecutor(new IQuartzTaskFilter[] { filter1,filter2 }.ToList());
         //执行任务及过滤器栈
         await executor.Execute(()=>task.ExecuteAsync(new TaskExecutingContext 
         {
             
         }));
     }

    有建议和不正之处欢迎指出,多多学习!

  • 相关阅读:
    洛谷 P1763 状态压缩dp+容斥原理
    hdu4612 Warm up 缩点+树的直径
    UVA-315 无向图求割点个数
    mysql 严格模式 Strict Mode说明
    bak文件恢复成 SQL2005 数据库 的全程讲解
    vps(windows2003)安全设置参考
    window下lamp环境搭建
    centos虚拟机配置网卡连接
    linux Tar 命令参数详解
    linux 打包和压缩的概念和区别
  • 原文地址:https://www.cnblogs.com/chaeyeon/p/12631697.html
Copyright © 2011-2022 走看看