如何寫任務計劃
在一些需要定時執行的任務時,比如:定時備份數據庫,定時的獲取網絡數據等都需要計劃任務。Window也有計劃任務但是有很多的缺點,必須手動配置,而 且部署起來也很麻煩,時間的精度爲一分鐘,只能對應用程序配置任務。這裏實現的任務計劃是可以自己編程,可以很靈活,時間的精度爲一秒,而且不是通過輪詢 時間實現的,效率比較高,。你可以在Windows
服務中寫一個服務,用它來管理所有的計劃任務邏輯。
類庫源代碼如下: /********************************************************************************************
* (C)2003-2005 C2217 Studio
* 保留所有權利
*
* 文件名稱: task.cs
* 文件ID:
* 編程語言: C#
* 文件說明: 實現計劃任務的調度機制。可以顯示多種任務調度機制(定義時間精確到秒):
* 1.立即執行(一次)
* 2.計劃執行(一次,可定義任務開始執行的日期)
* 3.立即執行(循環執行,多次)
* 4.計劃執行(循環執行,多次,可定義任務開始執行的日期)
* 可以通過實現接口ISchedule 制定自己的執行計劃
*
* 當前版本: 1.0
* 替換版本:
*
* 作者: 鄧楊均
* EMail: [email protected]
* 創建日期: 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>
[TestFixture]
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>
[Test]
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
}
類庫源代碼如下: /********************************************************************************************
* (C)2003-2005 C2217 Studio
* 保留所有權利
*
* 文件名稱: task.cs
* 文件ID:
* 編程語言: C#
* 文件說明: 實現計劃任務的調度機制。可以顯示多種任務調度機制(定義時間精確到秒):
* 1.立即執行(一次)
* 2.計劃執行(一次,可定義任務開始執行的日期)
* 3.立即執行(循環執行,多次)
* 4.計劃執行(循環執行,多次,可定義任務開始執行的日期)
* 可以通過實現接口ISchedule 制定自己的執行計劃
*
* 當前版本: 1.0
* 替換版本:
*
* 作者: 鄧楊均
* EMail: [email protected]
* 創建日期: 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>
[TestFixture]
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>
[Test]
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
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.