编程实现计划任务(转)
http://blog.csdn.net/yangjundeng/article/details/343047
在一些需要定时执行的任务时,比如:定时备份数据库,定时的获取网络数据等都需要计划任务。Window也有计划任务但是有很多的缺点,必须手动配置,而且部署起来也很麻烦,时间的精度为一分钟,只能对应用程序配置任务。这里实现的任务计划是可以自己编程,可以很灵活,时间的精度为一秒,而且不是通过轮询时间实现的,效率比较高,。你可以在Windows 服务中写一个服务,用它来管理所有的计划任务逻辑。
类库源代码如下:
/********************************************************************************************
* (C)2003-2005 C2217 Studio
* 保留所有权利
*
* 文件名称: task.cs
* 文件ID:
* 编程语言: C#
* 文件说明: 实现计划任务的调度机制。可以实现多种任务调度机制(定义时间精确到秒):
* 1.立即执行(一次)
* 2.计划执行(一次,可定义任务开始执行的日期)
* 3.立即执行(循环执行,多次)
* 4.计划执行(循环执行,多次,可定义任务开始执行的日期)
* 可以通过实现接口ISchedule 制定自己的执行计划
*
* 当前版本: 1.0
* 替换版本:
*
* 作者: 邓杨均
* EMail: dyj057@gmail.com
* 创建日期: 2005-4-8
* 最后修改日期: 2005-4-8
*
*历史修改记录:
********************************************************************************************/
using System;
using System.Collections;
using System.Threading;
//using NUnit.Framework;
namespace Ibms.Utility.Task
{
#region 任务计划接口和一些标准实现
/// <summary>
/// 计划的接口
/// </summary>
public interface ISchedule
{
/// <summary>
/// 返回最初计划执行时间
/// </summary>
DateTime ExecutionTime
{
get;
set;
}
/// <summary>
/// 初始化执行时间于现在时间的时间刻度差
/// </summary>
long DueTime
{
get;
}
/// <summary>
/// 循环的周期
/// </summary>
long Period
{
get;
}
}
/// <summary>
/// 计划立即执行任务
/// </summary>
public class ImmediateExecution:ISchedule
{
#region ISchedule 成员
public DateTime ExecutionTime
{
get
{
// TODO: 添加 ImmediatelyShedule.ExecutionTime getter 实现
return DateTime.Now;
}
set
{
;
}
}
public long DueTime
{
get
{
return 0;
}
}
public long Period
{
get
{
// TODO: 添加 ImmediatelyShedule.Period getter 实现
return Timeout.Infinite;
}
}
#endregion
}
/// <summary>
/// 计划在某一未来的时间执行一个操作一次,如果这个时间比现在的时间小,就变成了立即执行的方式
/// </summary>
public class ScheduleExecutionOnce:ISchedule
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="schedule">计划开始执行的时间</param>
public ScheduleExecutionOnce( DateTime schedule)
{
m_schedule = schedule;
}
private DateTime m_schedule;
#region ISchedule 成员
public DateTime ExecutionTime
{
get
{
// TODO: 添加 ScheduleExecutionOnce.ExecutionTime getter 实现
return m_schedule;
}
set
{
m_schedule = value;
}
}
/// <summary>
/// 得到该计划还有多久才能运行
/// </summary>
public long DueTime
{
get
{
long ms=( m_schedule.Ticks- DateTime.Now.Ticks)/10000;
if( ms < 0 ) ms=0;
return ms;
}
}
public long Period
{
get
{
// TODO: 添加 ScheduleExecutionOnce.Period getter 实现
return Timeout.Infinite;
}
}
#endregion
}
/// <summary>
/// 周期性的执行计划
/// </summary>
public class CycExecution:ISchedule
{
/// <summary>
/// 构造函数,在一个将来时间开始运行
/// </summary>
/// <param name="shedule">计划执行的时间</param>
/// <param name="period">周期时间</param>
public CycExecution(DateTime shedule,TimeSpan period)
{
m_schedule = shedule;
m_period = period;
}
/// <summary>
/// 构造函数,马上开始运行
/// </summary>
/// <param name="period">周期时间</param>
public CycExecution(TimeSpan period)
{
m_schedule = DateTime.Now;
m_period = period;
}
private DateTime m_schedule;
private TimeSpan m_period;
#region ISchedule 成员
public long DueTime
{
get
{
long ms=( m_schedule.Ticks- DateTime.Now.Ticks)/10000;
if( ms < 0 ) ms=0;
return ms;
}
}
public DateTime ExecutionTime
{
get
{
// TODO: 添加 CycExecution.ExecutionTime getter 实现
return m_schedule;
}
set
{
m_schedule = value;
}
}
public long Period
{
get
{
// TODO: 添加 CycExecution.Period getter 实现
return m_period.Ticks/10000;
}
}
#endregion
}
#endregion
#region 任务实现
/// <summary>
/// 计划任务基类
/// 启动的任务会在工作工作线程中完成,调用启动方法后会立即返回。
///
/// 用法:
/// (1)如果你要创建自己的任务,需要从这个类继承一个新类,然后重载Execute(object param)方法.
/// 实现自己的任务,再把任务加入到任务管理中心来启动和停止。
/// 比如:
/// TaskCenter center = new TaskCenter();
/// Task newTask = new Task( new ImmediateExecution());
/// center.AddTask(newTask);
/// center.StartAllTask();
/// (2)直接把自己的任务写入TimerCallBack委托,然后生成一个Task类的实例,
/// 设置它的Job和JobParam属性,再Start就可以启动该服务了。此时不能够再使用任务管理中心了。
/// 比如:
/// Task newTask = new Task( new ImmediateExecution());
/// newTask.Job+= new TimerCallback(newTask.Execute);
/// newTask.JobParam = "Test immedialte task"; //添加自己的参数
/// newTask.Start();
///
/// </summary>
public class Task
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="schedule">为每个任务制定一个执行计划</param>
public Task(ISchedule schedule)
{
if(schedule==null)
{
throw (new ArgumentNullException("schedule") );
}
m_schedule =schedule;
}
/// <summary>
/// 启动任务
/// </summary>
public void Start()
{
//启动定时器
m_timer = new Timer (m_execTask, m_param,m_schedule.DueTime ,m_schedule.Period);
}
/// <summary>
/// 停止任务
/// </summary>
public void Stop()
{
//停止定时器
m_timer.Change(Timeout.Infinite,Timeout.Infinite);
}
/// <summary>
/// 任务内容
/// </summary>
/// <param name="param">任务函数参数</param>
public virtual void Execute(object param)
{
//你需要重载该函数,但是需要在你的新函数中调用base.Execute();
m_lastExecuteTime = DateTime.Now;
if(m_schedule.Period == Timeout.Infinite)
{
m_nextExecuteTime = DateTime.MaxValue; //下次运行的时间不存在
}
else
{
TimeSpan period = new TimeSpan(m_schedule.Period * 1000);
m_nextExecuteTime = m_lastExecuteTime +period;
}
}
/// <summary>
/// 任务下执行时间
/// </summary>
public DateTime NextExecuteTime
{
get
{
return m_nextExecuteTime;
}
}
DateTime m_nextExecuteTime;
/// <summary>
/// 执行任务的计划
/// </summary>
public ISchedule Shedule
{
get
{
return m_schedule;
}
}
private ISchedule m_schedule;
/// <summary>
/// 系统定时器
/// </summary>
private Timer m_timer;
/// <summary>
/// 任务内容
/// </summary>
public TimerCallback Job
{
get
{
return m_execTask;
}
set
{
m_execTask= value;
}
}
private TimerCallback m_execTask;
/// <summary>
/// 任务参数
/// </summary>
public object JobParam
{
set
{
m_param = value;
}
}
private object m_param;
/// <summary>
/// 任务名称
/// </summary>
public string Name
{
get
{
return m_name;
}
set
{
m_name = value;
}
}
private string m_name;
/// <summary>
/// 任务描述
/// </summary>
public string Description
{
get
{
return m_description;
}
set
{
m_description = value;
}
}
private string m_description;
/// <summary>
/// 该任务最后一次执行的时间
/// </summary>
public DateTime LastExecuteTime
{
get
{
return m_lastExecuteTime;
}
}
private DateTime m_lastExecuteTime;
}
#endregion
#region 启动任务
/// <summary>
/// 任务管理中心
/// 使用它可以管理一个或则多个同时运行的任务
/// </summary>
public class TaskCenter
{
/// <summary>
/// 构造函数
/// </summary>
public TaskCenter()
{
m_scheduleTasks = new ArrayList();
}
/// <summary>
/// 添加任务
/// </summary>
/// <param name="newTask">新任务</param>
public void AddTask(Task newTask)
{
m_scheduleTasks.Add(newTask);
}
/// <summary>
/// 删除任务
/// </summary>
/// <param name="delTask">将要删除的任务,你可能需要停止掉该任务</param>
public void DelTask(Task delTask)
{
m_scheduleTasks.Remove(delTask);
}
/// <summary>
/// 启动所有的任务
/// </summary>
public void StartAllTask()
{
foreach(Task task in ScheduleTasks)
{
StartTask(task);
}
}
/// <summary>
/// 启动一个任务
/// </summary>
/// <param name="task"></param>
public void StartTask(Task task)
{
//标准启动方法
if(task.Job == null)
{
task.Job+= new TimerCallback(task.Execute);
}
task.Start();
}
/// <summary>
/// 终止所有的任务
/// </summary>
public void TerminateAllTask()
{
foreach(Task task in ScheduleTasks)
{
TerminateTask(task);
}
}
/// <summary>
/// 终止一个任务
/// </summary>
/// <param name="task"></param>
public void TerminateTask(Task task)
{
task.Stop();
}
/// <summary>
/// 获得所有的任务
/// </summary>
ArrayList ScheduleTasks
{
get
{
return m_scheduleTasks;
}
}
private ArrayList m_scheduleTasks;
/// <summary>
/// 单元测试代码
/// </summary>
public void TestTaskCenter()
{
TaskCenter center = new TaskCenter();
//Test immedialte task
Task newTask = new Task( new ImmediateExecution());
newTask.Job+= new TimerCallback(newTask.Execute);
newTask.JobParam = "Test immedialte task";
//Test excute once task
DateTime sheduleTime = DateTime.Now.AddSeconds(10);
ScheduleExecutionOnce future= new ScheduleExecutionOnce(sheduleTime);
Task sheduleTask = new Task( future);
sheduleTask.Job+= new TimerCallback(sheduleTask.Execute);
sheduleTask.JobParam = "Test excute once task";
//Test cyc task at once
CycExecution cyc = new CycExecution( new TimeSpan(0,0,2));
Task cysTask = new Task(cyc);
cysTask.Job+= new TimerCallback(cysTask.Execute);
cysTask.JobParam = "Test cyc task";
//Test cys task at schedule
CycExecution cycShedule = new CycExecution( DateTime.Now.AddSeconds(8),new TimeSpan(0,0,2));
Task cycSheduleTask = new Task(cycShedule);
cycSheduleTask.Job+= new TimerCallback(cysTask.Execute);
cycSheduleTask.JobParam = "Test cyc Shedule task";
center.AddTask(newTask);
center.AddTask(sheduleTask);
center.AddTask(cysTask);
center.AddTask(cycSheduleTask);
center.StartAllTask();
Console.ReadLine();
Console.WriteLine(newTask.LastExecuteTime);
}
}
#endregion
}
测试代码:
using System;
using System.Threading;
namespace Ibms.Utility.Task.Test
{
/// <summary>
/// 解释怎么创建自己的任务类,和使用它们
/// </summary>
class TestTask:Ibms.Utility.Task.Task
{
public TestTask(ISchedule schedule)
:base(schedule)
{
}
public override void Execute(object param)
{
//一定要保留
base.Execute (param);
Console.WriteLine("Begin to execute a long job...NextExecuteTime:{0}",this.NextExecuteTime);
Thread.Sleep(5000);
Console.WriteLine("Test Tast execute job.Last ExecuteTime {0}, ",
this.LastExecuteTime
);
}
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
TaskCenter center = new TaskCenter();
//Test immedialte task
Task newTask = new TestTask( new ImmediateExecution());
newTask.JobParam = "Test immedialte task";
//Test excute once task
DateTime sheduleTime = DateTime.Now.AddSeconds(10);
ScheduleExecutionOnce future= new ScheduleExecutionOnce(sheduleTime);
Task sheduleTask = new TestTask(future);
sheduleTask.JobParam = "Test excute once task";
//Test cyc task at once
CycExecution cyc = new CycExecution( new TimeSpan(0,0,2));
Task cysTask = new TestTask(cyc);
cysTask.JobParam = "Test cyc task";
//Test cys task at schedule
CycExecution cycShedule = new CycExecution( DateTime.Now.AddSeconds(8),new TimeSpan(0,0,2));
Task cycSheduleTask = new TestTask(cycShedule);
cycSheduleTask.JobParam = "Test cyc Shedule task";
center.AddTask(newTask);
center.AddTask(sheduleTask);
center.AddTask(cysTask);
center.AddTask(cycSheduleTask);
center.StartAllTask();
Console.ReadLine();
Console.WriteLine("terminate all task");
center.TerminateAllTask();
Console.ReadLine();
}
}
}