最近一个 c/s项目中需要用到定时任务,也就是说每天定时几点给客户发送短信的功能。
思考过后,最后决定这么设计。。。。
由于是定时任务,不是间隔多少时间来执行,所以需要计算定时的时间和当前时间相差毫秒数,然后就可以设置Timer的Interval了,
该任务是每天执行,所以也可以简单的处理了
1、首先抽象出定时任务类:AbstractTask
属性 Cron:定时的时间,如 10:00:00
TaskName:任务名称
NextTime:任务下次执行时间
主要方法 Start() : 开始任务
Stop() :停止任务
abstract Run() :抽象的run方法供子类覆写 来实现自己任务功能
详细代码如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace TaskCenter
6 {
7 /// <summary>
8 /// 定时任务抽象类
9 /// </summary>
10 public abstract class AbstractTask
11 {
12 private string cron = " 10:00:00 " ; // 定时时间 时:分:秒
13 private string taskName = " NoName " ;
14 private System.Timers.Timer timer = new System.Timers.Timer();
15 #region 一些属性
16 /// <summary>
17 /// 获取或设置该任务名称
18 /// </summary>
19 public string TaskName
20 {
21 get { return taskName; }
22 set { taskName = value; }
23 }
24 private DateTime nextTime = new DateTime();
25
26 /// <summary>
27 /// 取得任务下次执行时间
28 /// </summary>
29 public DateTime NextTime
30 {
31 get { return nextTime; }
32 // set { nextTime = value; }
33 }
34 /// <summary>
35 /// 设置任务执行时间,默认 10:00:00
36 /// 如果时间格式出错,使用默认值
37 /// </summary>
38 public string Cron
39 {
40 get { return cron; }
41 set
42 {
43 // TODO:判断是否有效
44 DateTime tmp;
45 if (DateTime.TryParse(value, out tmp))
46 {
47 cron = value;
48 }
49 }
50 }
51 #endregion
52
53 /// <summary>
54 /// 停止任务
55 /// </summary>
56 public void Stop()
57 {
58 if (timer != null )
59 {
60 timer.Stop();
61 timer.Enabled = false ;
62 }
63 }
64
65 /// <summary>
66 /// 开始执行任务
67 /// </summary>
68 public void Start()
69 {
70 ProcessTaskTime();
71 }
72
73 /// <summary>
74 /// 处理下次执行任务的时间
75 /// </summary>
76 private void ProcessTaskTime()
77 {
78 double interval = 0 ;
79 // 解析时间 并 设置 timer 间隔时间
80 if ( ! "" .Equals(Cron))
81 {
82 DateTime execDateTime = ExecTime(cron); // 任务执行时间
83 Console.WriteLine( string .Format( " 任务:[{0}] 下次执行时间:{1} " ,taskName,execDateTime.ToString()));
84 interval = (execDateTime - DateTime.Now).TotalMilliseconds;
85 timer.Interval = interval;
86 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
87 timer.Enabled = true ;
88 }
89 }
90
91 // 计算下次执行时间
92 private DateTime ExecTime( string str)
93 {
94 DateTime dt = new DateTime();
95 try
96 {
97 // dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
98 // Int32.Parse(strs[0]), Int32.Parse(strs[1]), Int32.Parse(strs[2]));
99 dt = DateTime.Parse(str);
100 DateTime dtNow = DateTime.Now;
101
102 // 判断今天能否执行
103 TimeSpan ts = dtNow - dt;
104 if (ts.TotalMilliseconds > 0 )
105 {
106 // 今天已经过了执行时间了,只能明天了
107 dt = dt.AddDays( 1 );
108 }
109 nextTime = dt;
110 }
111 catch
112 { }
113 return dt;
114 }
115
116 void timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e)
117 {
118 ProcessTaskTime();
119 Run();
120 }
121
122 /// <summary>
123 /// 定时任务主入口
124 /// </summary>
125 protected abstract void Run();
126 }
127 }
128
2、新建一个定时任务类 TaskTest 继承AbstractTask抽象类
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace TaskCenter
6 {
7 public class TaskTest:AbstractTask
8 {
9 protected override void Run()
10 {
11 Console.WriteLine( " =====这里执行了自己的任务!===== " );
12 }
13 }
14 }
15
3、测试任务执行
只需要实例化定时任务类,执行它的 Start方法即可。。
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8
9 namespace TaskCenter
10 {
11 public partial class Form1 : Form
12 {
13 public Form1()
14 {
15 InitializeComponent();
16 }
17
18 private void Form1_Load( object sender, EventArgs e)
19 {
20 AbstractTask task = new TaskTest();
21 task.TaskName = " 测试的定时任务 " ;
22 task.Cron = " 20:31:00 " ;//定时时间,每天执行
23
24 task.Start();
25 }
26 }
27 }
28
项目启动以后就可以看到
任务:[测试的定时任务] 下次执行时间:2010/8/7 20:31:00
任务:[测试的定时任务] 下次执行时间:2010/8/8 20:31:00
=====这里执行了自己的任务!=====
好了,到此为止,一个简单的定时任务程序搞定了,后续还可以继续优化,将定时任务的时间改成多种形式,类似于linux中的cron,呵呵
到时候只需要修改 抽象类中的 ExecTime方法,让他根据不同的条件 计算出下次执行的时间即可。
最后还可以加一个调度中心来管理这些定时任务。。。。。。