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

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

呵呵

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

恩,努力控烟吧!

废话说完了,就进入咱们的小程序: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( * );
}
} 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();
}
}
}

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()
{ }
}
}

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();
private readonly List<ICronJob> _cronJobs = new List<ICronJob>();
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);
}
}
}
}

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<int> Minutes;
public List<int> Hours;
public List<int> DaysOfMonth;
public List<int> Months;
public List<int> 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 > ;//== 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[].ToString()); if (matches.Count > )
GenerateHours(matches[].ToString());
else
GenerateHours("*"); if (matches.Count > )
GenerateDaysOfMonth(matches[].ToString());
else
GenerateDaysOfMonth("*"); if (matches.Count > )
GenerateMonths(matches[].ToString());
else
GenerateMonths("*"); if (matches.Count > )
GenerateDaysOfWeeks(matches[].ToString());
else
GenerateDaysOfWeeks("*");
} private void GenerateMinutes(string match)
{
Minutes = GenerateValues(match, , );
} private void GenerateHours(string match)
{
Hours = GenerateValues(match, , );
} private void GenerateDaysOfMonth(string match)
{
DaysOfMonth = GenerateValues(match, , );
} private void GenerateMonths(string match)
{
Months = GenerateValues(match, , );
} private void GenerateDaysOfWeeks(string match)
{
DaysOfWeek = GenerateValues(match, , );
} private List<int> 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<int>();
} private List<int> DividedArray(string configuration, int start, int max)
{
if (!DividedRegex.IsMatch(configuration))
return new List<int>(); List<int> ret = new List<int>();
string[] split = configuration.Split("/".ToCharArray());
int divisor = int.Parse(split[]); for (int i = start; i < max; ++i)
if (i % divisor == )
ret.Add(i); return ret;
} private List<int> RangeArray(string configuration)
{
if (!RangeRegex.IsMatch(configuration))
return new List<int>(); List<int> ret = new List<int>();
string[] split = configuration.Split("-".ToCharArray());
int start = int.Parse(split[]);
int end = ;
if (split[].Contains("/"))
{
split = split[].Split("/".ToCharArray());
end = int.Parse(split[]);
int divisor = int.Parse(split[]); for (int i = start; i < end; ++i)
if (i % divisor == )
ret.Add(i);
return ret;
}
else
end = int.Parse(split[]); for (int i = start; i <= end; ++i)
ret.Add(i); return ret;
} private List<int> WildArray(string configuration, int start, int max)
{
if (!WildRegex.IsMatch(configuration))
return new List<int>(); List<int> ret = new List<int>(); for (int i = start; i < max; ++i)
ret.Add(i); return ret;
} private List<int> ListArray(string configuration)
{
if (!ListRegex.IsMatch(configuration))
return new List<int>(); List<int> ret = new List<int>(); string[] split = configuration.Split(",".ToCharArray()); foreach (string s in split)
ret.Add(int.Parse(s)); return ret;
}
}
}

作业代码如下:

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");
}
}
}

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");
}
}
}

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

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

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

OK,源码地址为:https://download.csdn.net/download/wolongbb/10276057

@陈卧龙的博客

最新文章

  1. Dapper入门学习
  2. ABP理论学习之仓储
  3. fcntl函数
  4. 【转】虚拟机VMware3种网络模式(桥接、nat、Host-only)的工作原理
  5. app状态监听广播
  6. JQuery_给元素添加或删除类等以及CSS()方法
  7. 200 OK (from cache) 与 304 Not Modified
  8. Pivotal Cloud Foundry学习笔记(1)
  9. mvc 笔记
  10. AngularJS 深入理解 $scope 转载▼
  11. mac osx 10.9 ftp server端口
  12. 浅谈Web Api配合SignalR的跨域支持
  13. java基础-修饰符
  14. liunx 同步时间
  15. maven使用jstl表达式和The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application解决
  16. Java 的强引用、弱引用、软引用、虚引用
  17. Docker CMD in detail
  18. 挑战常规--为什么不应该使用Jsonp进行跨域
  19. jQuery preventDefault() ,stopPropagation(),stopImmediatePropagation()
  20. MVC5干货篇,目录和路由

热门文章

  1. 【转】64位系统下无法使用libpam-mysql的md5
  2. SoapUI&#160;SoapUI接口测试之编码设置
  3. drop all database objects
  4. 第七章 Hyper-V 2012 R2 授权管理
  5. Linq2DB之研究和探索
  6. windows 10 安装TortoiseSVN.msi时报2503的错误
  7. 这不是我想要的ABAP开发者
  8. 兼容IE8及以上的常用css选择器
  9. 网络编程_IP对象_InetAddress
  10. Properties集合_练习