来自:清泛网 - http://www.tsingfun.com/html/2015/dev_0811/CSharp_Plan_Task.html
C#只提供Timer定时器(C++ SetTimer 类似),通过设置一个时间间隔来定时触发执行任务。那么定点执行任务怎么实现呢?
原理: 每次通过计算得出下次定点任务与现在时点的事件间隔,作为Timer的时间间隔,从而实现任务的定点执行。原理比较简单,代码中都有注释,有类似需求的童鞋可以直接用作项目中,免测试哦~~~
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace PlanDemoService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
// 每天执行一次的时间点(最好写在配置中,这里为了方便展示)
private string onceDoStr = "18:00";
private DateTime onceDoTime;
// 定时执行一次
private Timer onceDoTimer = new Timer();
/// <summary>
/// 定时器触发事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnceDoTimer_Elapsed(object sender, ElapsedEventArgs e)
{
UpdateOnceDoTimePeriod();
// 更新下次执行间隔
SetNextOnceDoInterval();
if (DateTime.Now.ToString("HH:mm").CompareTo(onceDoStr.Trim()) >= 0)
{
// 可能由于系统原因导致触发过早的,不执行
onceDoMain();
}
}
/// <summary>
/// 设置定时器间隔时间
/// </summary>
private void SetNextOnceDoInterval()
{
TimeSpan spanNextDay = new TimeSpan(1, 0, 0, 0);
if (DateTime.Now < onceDoTime)
{
onceDoTimer.Interval = (onceDoTime - DateTime.Now).TotalMilliseconds;
Loger.Log(string.Format("定时任务将于{0}执行一次。", onceDoTime.ToString("yyyy-MM-dd HH:mm:ss")), "PlanDemoService");
}
if (DateTime.Now > onceDoTime)
{
onceDoTimer.Interval = (onceDoTime + spanNextDay - DateTime.Now).TotalMilliseconds;
Loger.Log(string.Format("下次定时任务将于{0}执行一次。", (onceDoTime + spanNextDay).ToString("yyyy-MM-dd HH:mm:ss")), "PlanDemoService");
}
}
/// <summary>
/// 更新任务触发时间(按每天最新日期)
/// </summary>
private void UpdateOnceDoTimePeriod()
{
string[] parts = onceDoStr.Split(':');
onceDoTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
int.Parse(parts[0]), int.Parse(parts[1]), 0);
}
/// <summary>
/// 任务执行
/// </summary>
private void onceDoMain()
{
Loger.Log("任务执行!", "PlanDemoService");
}
protected override void OnStart(string[] args)
{
try
{
UpdateOnceDoTimePeriod();
}
catch (Exception e)
{
Loger.Log("时间配置有误!" + e.Message, "PlanDemoService");
throw e;
}
onceDoTimer.Elapsed += new ElapsedEventHandler(OnceDoTimer_Elapsed);
SetNextOnceDoInterval();
onceDoTimer.Start();
}
protected override void OnStop()
{
onceDoTimer.Stop();
Loger.Log("服务已停止!", "PlanDemoService");
}
}
}
完整的工程代码,
点此下载
。
关注我们的微博:http://weibo.com/tsingfun