博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 简单的 Job 作业~
阅读量:7098 次
发布时间:2019-06-28

本文共 11510 字,大约阅读时间需要 38 分钟。

改变之前的前言,这次咱这样写:

一个习惯只需十天的坚持就可以养成,坏习惯也不例外!吸烟喝酒的我能否做到十天不吸烟喝酒呢?

呵呵

养成习惯关键还要看决心和意志力

恩,努力控烟吧!

废话说完了,就进入咱们的小程序:Job作业。

我这里所说的Job作业并没有 Quartz 或者 Quartz.Net 那么高大尚,今天和大家介绍的作业是一个非常非常轻量级的框架,与其说框架倒不如说是一个只有不足千行的代码!

哈哈

如下:

按照我的步骤,一起来构建一个 Job 作业调度的小项目,

步骤一:新建一个解决方案,姑且命名为Job吧,如下:

此解决方案有两个项目,一个是Job控制台项目,一个是CronJob类库,

步骤二:复制粘贴下边的代码

控制台 Program.cs 代码如下

using CronJob;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace Job{    class Program    {        private static readonly CronMon CronMon = new CronMon();        static void Main(string[] args)        {            Start();            while (true)            {                Console.WriteLine(string.Format("{0}: Running", DateTime.Now.ToString("s")));                Thread.Sleep(60 * 1000);            }        }        public static void Start()        {            Init();            CronMon.Start();        }        //Cron 表达式范例        //TODO 移到配置文件里        //* * * * * = Minutes Hours Day-of-Month Month Day-of-Week        //每隔1分钟执行一次:*/1 * * *        //每天23点执行一次:0 23 * *        //每天凌晨1点执行一次:0 1 * *        //每月1号凌晨1点执行一次:0 1 1 *        //在26分、29分、33分执行一次:26,29,33 * * *        //每天的0点、13点、18点、21点都执行一次: 0 0,13,18,21 * *        private static void Init()        {            CronMon.AddJob(new JobFoobar("*/1 * * *"));            CronMon.AddJob(new JobFoobar2("*/1 * * *"));        }        public static void Abort()        {            CronMon.Stop();        }    }}
View Code

CronJob类库代码如下:

CronJob类库中有两个文件夹,一个是基类文件夹(Base),一个是你的作业文件夹(Jobs):

关于基类文件夹没什么可说的,关于作业文件夹是指你的项目中需要做调度的任务都可以写成Job放在这个文件夹中,

基类代码如下:

CronJobBase.cs

using System;using System.Threading;namespace CronJob{    public interface ICronJob    {        void Run(DateTime dateTime);        void Abort();    }    public class CronJobBase : ICronJob    {        private readonly object _lock = new object();        private readonly CronSchedule _cronSchedule;        private Thread _thread;        public CronJobBase(string schedule)        {            _cronSchedule = new CronSchedule(schedule);        }        public void Run(DateTime dateTime)        {            lock (_lock)            {                if (!_cronSchedule.IsTime(dateTime))                    return;                if (_thread!= null && _thread.ThreadState == ThreadState.Running)                    return;                _thread = new Thread(ExecuteHandler);                _thread.Start();            }        }        public void Abort()        {            _thread.Abort();        }        private void ExecuteHandler()        {            try            {                Execute();            }            catch (Exception ex)            {                Console.WriteLine("Error:", ex);            }        }        protected virtual void Execute()        {        }    }}
View Code

CronMon.cs

using System;using System.Collections.Generic;using System.Timers;using System.Threading;namespace CronJob{    public interface ICronMon    {        void AddJob(ICronJob job);        void Start();        void Stop();    }    public class CronMon : ICronMon    {        private readonly System.Timers.Timer _timer = new System.Timers.Timer(30000);        private readonly List
_cronJobs = new List
(); private DateTime _last = DateTime.Now; public CronMon() { _timer.AutoReset = true; _timer.Elapsed += timer_elapsed; } public void AddJob(ICronJob job) { _cronJobs.Add(job); } public void Start() { _timer.Start(); } public void Stop() { _timer.Stop(); foreach (var cronJob in _cronJobs) { var job = (CronJobBase) cronJob; job.Abort(); } } private void timer_elapsed(object sender, ElapsedEventArgs e) { if (DateTime.Now.Minute != _last.Minute) { _last = DateTime.Now; foreach (ICronJob job in _cronJobs) job.Run(DateTime.Now); } } }}
View Code

CronSchedule.cs

using System;using System.Collections.Generic;using System.Text.RegularExpressions;namespace CronJob{    public interface ICronSchedule    {        bool IsValid(string expression);        bool IsTime(DateTime dateTime);    }    public class CronSchedule : ICronSchedule    {        private static readonly Regex DividedRegex = new Regex(@"(\*/\d+)");        private static readonly Regex RangeRegex = new Regex(@"(\d+\-\d+)\/?(\d+)?");        private static readonly Regex WildRegex = new Regex(@"(\*)");        private static readonly Regex ListRegex = new Regex(@"(((\d+,)*\d+)+)");        private static readonly Regex ValidationRegex = new Regex(DividedRegex + "|" + RangeRegex + "|" + WildRegex + "|" + ListRegex);        private readonly string _expression;        public List
Minutes; public List
Hours; public List
DaysOfMonth; public List
Months; public List
DaysOfWeek; public CronSchedule() { } public CronSchedule(string expressions) { _expression = expressions; Generate(); } private bool isValid() { return IsValid(_expression); } public bool IsValid(string expression) { MatchCollection matches = ValidationRegex.Matches(expression); return matches.Count > 0;//== 5; } public bool IsTime(DateTime dateTime) { return Minutes.Contains(dateTime.Minute) && Hours.Contains(dateTime.Hour) && DaysOfMonth.Contains(dateTime.Day) && Months.Contains(dateTime.Month) && DaysOfWeek.Contains((int)dateTime.DayOfWeek); } private void Generate() { if (!isValid()) return; MatchCollection matches = ValidationRegex.Matches(_expression); GenerateMinutes(matches[0].ToString()); if (matches.Count > 1) GenerateHours(matches[1].ToString()); else GenerateHours("*"); if (matches.Count > 2) GenerateDaysOfMonth(matches[2].ToString()); else GenerateDaysOfMonth("*"); if (matches.Count > 3) GenerateMonths(matches[3].ToString()); else GenerateMonths("*"); if (matches.Count > 4) GenerateDaysOfWeeks(matches[4].ToString()); else GenerateDaysOfWeeks("*"); } private void GenerateMinutes(string match) { Minutes = GenerateValues(match, 0, 60); } private void GenerateHours(string match) { Hours = GenerateValues(match, 0, 24); } private void GenerateDaysOfMonth(string match) { DaysOfMonth = GenerateValues(match, 1, 32); } private void GenerateMonths(string match) { Months = GenerateValues(match, 1, 13); } private void GenerateDaysOfWeeks(string match) { DaysOfWeek = GenerateValues(match, 0, 7); } private List
GenerateValues(string configuration, int start, int max) { if (DividedRegex.IsMatch(configuration)) return DividedArray(configuration, start, max); if (RangeRegex.IsMatch(configuration)) return RangeArray(configuration); if (WildRegex.IsMatch(configuration)) return WildArray(configuration, start, max); if (ListRegex.IsMatch(configuration)) return ListArray(configuration); return new List
(); } private List
DividedArray(string configuration, int start, int max) { if (!DividedRegex.IsMatch(configuration)) return new List
(); List
ret = new List
(); string[] split = configuration.Split("/".ToCharArray()); int divisor = int.Parse(split[1]); for (int i = start; i < max; ++i) if (i % divisor == 0) ret.Add(i); return ret; } private List
RangeArray(string configuration) { if (!RangeRegex.IsMatch(configuration)) return new List
(); List
ret = new List
(); string[] split = configuration.Split("-".ToCharArray()); int start = int.Parse(split[0]); int end = 0; if (split[1].Contains("/")) { split = split[1].Split("/".ToCharArray()); end = int.Parse(split[0]); int divisor = int.Parse(split[1]); for (int i = start; i < end; ++i) if (i % divisor == 0) ret.Add(i); return ret; } else end = int.Parse(split[1]); for (int i = start; i <= end; ++i) ret.Add(i); return ret; } private List
WildArray(string configuration, int start, int max) { if (!WildRegex.IsMatch(configuration)) return new List
(); List
ret = new List
(); for (int i = start; i < max; ++i) ret.Add(i); return ret; } private List
ListArray(string configuration) { if (!ListRegex.IsMatch(configuration)) return new List
(); List
ret = new List
(); string[] split = configuration.Split(",".ToCharArray()); foreach (string s in split) ret.Add(int.Parse(s)); return ret; } }}
View Code

作业代码如下:

Job1.cs

using CronJob;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CronJob{    public class JobFoobar : CronJobBase    {        public JobFoobar(string schedule)            : base(schedule)        {        }        protected override void Execute()        {           Console.WriteLine("作业开始执行");            //do your logic           Console.WriteLine("我是一个简答的Job作业,编号为:1");           //do your logic           Console.WriteLine("执行结束");           //throw new Exception("fake error");        }    }}
View Code

Job2.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CronJob{    public class JobFoobar2 : CronJobBase    {        public JobFoobar2(string schedule)            : base(schedule)        {        }        protected override void Execute()        {            Console.WriteLine("作业开始执行");            //do your logic            Console.WriteLine("我是一个简答的Job作业,编号为:2");            //do your logic            Console.WriteLine("执行结束");            //throw new Exception("fake error");        }    }}
View Code

OK,项目打造完成后,记得控制台项目引用基类项目,那么运行后,如下:

在我们的作业中设置的是每一分钟执行一次,

两分钟的时间,执行了两次!

OK,源码地址为:

@陈卧龙的博客

转载地址:http://qvhql.baihongyu.com/

你可能感兴趣的文章
Freemarker常用技巧(三)
查看>>
Java Gradle入门指南之依赖管理(添加依赖、仓库、版本冲突) (转)
查看>>
关闭注册表编辑器,重新启动计算机后生效。这样资源管理器重启后就不会自动重启了。...
查看>>
Knockout应用开发指南(完整版) 目录索引
查看>>
A example that using JQuery clone
查看>>
随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比...
查看>>
Android 使用JSON格式与服务器交互 中文乱码问题解决
查看>>
_DataStructure_C_Impl:链串
查看>>
openvas
查看>>
SecureCRT同时向多个终端发送命令
查看>>
【IntelliJ】IntelliJ IDEA常用设置及快捷键以及自定义Live templates
查看>>
indexOf 和 lastIndexOf 的区别
查看>>
spring boot整合activemq消息中间件
查看>>
Spark:java api实现word count统计
查看>>
mqtt-jmeter
查看>>
Android上的蓝牙通信功能的开发:BluetoothChat例程分析
查看>>
Eclipse快捷键大全(转载)
查看>>
Yahoo!网站性能最佳体验的34条黄金守则——图片、Coockie与移动应用
查看>>
微博采撷(一)
查看>>
【CLR的执行模型:加载公共语言运行库(3)】
查看>>