WEB后台定时任务服务类及实现 源代码

试用http://121.18.78.216/
希望各位提宝贵意见(自己的讨论群152524724),谢谢

特别鸣谢http://blog.csdn.net/Netself/article/details/5766398提供的源代码分享。

实现思路:

1、封装实现一个定时任务服务类

2、单独实现类 实现定时任务的处理。

3、在系统启动时启动一个新线程调用定时任务

源码如下:

1、封装实现一个定时任务服务类

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace MyQuery.Utils.TimerTask
{
/// <summary>
/// 定时任务委托方法
/// </summary>
public delegate void TimerTaskDelegate(params object[] parm);

/// <summary>
/// 定时任务接口类
/// </summary>
public interface ITimerTask
{
/// <summary>
/// 执行
/// </summary>
void Run();
}

/// <summary>
/// 定时任务服务类
/// 作者:Duyong 修改:贾世义
/// 编写日期:2010-07-25 2011-07-01
///</summary>
public class TimerTaskService
{

#region 定时任务实例成员

private TimerInfo timerInfo; //定时信息

private TimerTaskDelegate TimerTaskDelegateFun = null; //执行具体任务的委托方法

private object[] parm = null; //参数

private ITimerTask TimerTaskInstance = null; //执行具体任务的实例

private System.Timers.Timer time;//定时器

/// <summary>
/// 根据定时信息和执行具体任务的实例构造定时任务服务
/// </summary>
/// <param name="_timer">定时信息</param>
/// <param name="_interface">执行具体任务的实例</param>
private TimerTaskService(TimerInfo _timer, ITimerTask _interface)
{
timerInfo = _timer;
TimerTaskInstance = _interface;
}

/// <summary>
/// 根据定时信息和执行具体任务的委托方法构造定时任务服务
/// </summary>
/// <param name="_timer">定时信息</param>
/// <param name="trd">执行具体任务的委托方法</param>
private TimerTaskService(TimerInfo _timer, TimerTaskDelegate trd)
{
timerInfo = _timer;
TimerTaskDelegateFun = trd;
}

/// <summary>
/// 设置参数
/// </summary>
/// <param name="_parm"></param>
private void setParm(params object[] _parm)
{
parm = _parm;
}

/// <summary>
/// 启动定时任务
/// </summary>
public void Start()
{
if (timerInfo.Type == TimerTypes.TimeSpan)
{
time = new System.Timers.Timer(1000 * 60 * timerInfo.Value);
time.Enabled = true;
time.Elapsed += this.TimeOut;
time.Start();
}
else
{
//检查定时器
CheckTimer();
}
}

/// <summary>
/// 检查定时器
/// </summary>
private void CheckTimer()
{
//计算下次执行时间
DateTime? NextRunTime = getNextRunTime();
//如果无法获得执行时间则 不再执行
if (NextRunTime.HasValue)
{
while (true)
{
DateTime DateTimeNow = DateTime.Now;

//时间比较
bool dateComp = DateTimeNow.Year == NextRunTime.Value.Year && DateTimeNow.Month == NextRunTime.Value.Month && DateTimeNow.Day == NextRunTime.Value.Day;

bool timeComp = DateTimeNow.Hour == NextRunTime.Value.Hour && DateTimeNow.Minute == NextRunTime.Value.Minute && DateTimeNow.Second == NextRunTime.Value.Second;

//睡够一分钟 防止一分钟内重复执行
Thread.Sleep(60 * 1000);
//如果当前时间等式下次运行时间,则调用线程执行方法
if (dateComp && timeComp)
{
//调用执行处理方法
if (TimerTaskDelegateFun != null)
{
TimerTaskDelegateFun(parm);
}
else if (TimerTaskInstance != null)
{
TimerTaskInstance.Run();
}
//重新计算下次执行时间
NextRunTime = getNextRunTime();
}
}
}
}
/// <summary>
/// 定时器执行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TimeOut(object sender, EventArgs e)
{
//调用执行处理方法
if (TimerTaskDelegateFun != null)
{
TimerTaskDelegateFun(parm);
}
else if (TimerTaskInstance != null)
{
TimerTaskInstance.Run();
}
}

/// <summary>
/// 计算下一次执行时间
/// </summary>
/// <returns></returns>
private DateTime? getNextRunTime()
{
DateTime now = DateTime.Now;
if (now > timerInfo.StartDate)
{
int nowHH = now.Hour;
int nowMM = now.Minute;
int nowSS = now.Second;

int timeHH = timerInfo.RunTime.Hour;
int timeMM = timerInfo.RunTime.Minute;
int timeSS = timerInfo.RunTime.Second;

//设置执行时间对当前时间进行比较
bool nowTimeComp = nowHH < timeHH || (nowHH <= timeHH && nowMM < timeMM) || (nowHH <= timeMM && nowMM <= timeMM && nowSS < timeSS);
switch (timerInfo.Type)
{
//每天
case TimerTypes.EveryDay:
if (nowTimeComp)
{
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS);
}
else
{
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS).AddDays(1);
}
break;
//每周
case TimerTypes.DayOfWeek:
DayOfWeek ofweek = DateTime.Now.DayOfWeek;

int dayOfweek = Convert.ToInt32(DateTime.Now.DayOfWeek);

if (ofweek == DayOfWeek.Sunday) dayOfweek = 7;

if (dayOfweek < timerInfo.Value)
{
int addDays = timerInfo.Value - dayOfweek;
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS).AddDays(addDays);
}
else if (dayOfweek == timerInfo.Value && nowTimeComp)
{
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS);

}
else
{
int addDays = 7 - (dayOfweek - timerInfo.Value);
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS).AddDays(addDays);
}
break;
//每月
case TimerTypes.DayOfMonth:
if (now.Day < timerInfo.Value)
{
return new DateTime(now.Year, now.Month, timerInfo.Value, timeHH, timeMM, timeSS);
}
else if (now.Day == timerInfo.Value && nowTimeComp)
{
return new DateTime(now.Year, now.Month, now.Day, timeHH, timeMM, timeSS);
}
else
{
return new DateTime(now.Year, now.Month, timerInfo.Value, timeHH, timeMM, timeSS).AddMonths(1);
}
break;
}
}
return null;
}

#endregion


#region 创建定时任务静态方法

/// <summary>
/// 使用委托方法创建定时任务
/// </summary>
/// <param name="info"></param>
/// <param name="_ptrd"></param>
/// <param name="parm"></param>
/// <returns></returns>
public static Thread CreateTimerTaskService(TimerInfo info, TimerTaskDelegate _ptrd, params object[] parm)
{
TimerTaskService tus = new TimerTaskService(info, _ptrd);
tus.setParm(parm);

//创建启动线程
Thread ThreadTimerTaskService = new Thread(new ThreadStart(tus.Start));
return ThreadTimerTaskService;
}

/// <summary>
/// 使用实现定时接口ITimerTask的实例创建定时任务
/// </summary>
/// <param name="info"></param>
/// <param name="_ins"></param>
/// <returns></returns>
public static Thread CreateTimerTaskService(TimerInfo info, ITimerTask _ins)
{
TimerTaskService tus = new TimerTaskService(info, _ins);
//创建启动线程
Thread ThreadTimerTaskService = new Thread(new ThreadStart(tus.Start));
return ThreadTimerTaskService;
}

#endregion
}

/// <summary>
/// 定时信息类
/// </summary>
public class TimerInfo
{
/// <summary>
/// 类型:EveryDay(每天),DayOfWeek(每周),DayOfMonth(每月),DesDate(指定日期),LoopDays(循环天数)
/// </summary>
public TimerTypes Type = TimerTypes.EveryDay;
/// <summary>
/// 日期值:DayOfWeek,值为1-7表示周一到周日;DayOfMonth,值为1-31表示1号到31号;TimeSpan,值为间隔分钟数;TimerType为其它值时,此值无效
/// </summary>
public int Value = 1;
/// <summary>
/// 指定开始执行日期
/// </summary>
public DateTime StartDate = DateTime.MinValue;
/// <summary>
/// 设置的执行时间 仅时间有效
/// </summary>
public DateTime RunTime = DateTime.Now;
}

/// <summary>
/// 循环类型
/// </summary>
public enum TimerTypes
{
/// <summary>
/// 每天
/// </summary>
EveryDay = 0,
/// <summary>
/// 每周 几
/// </summary>
DayOfWeek = 1,
/// <summary>
/// 每月 几日
/// </summary>
DayOfMonth = 2,
/// <summary>
/// 每隔几分钟执行一次
/// </summary>
TimeSpan = 3
}
}

2、单独实现类 实现定时任务的处理。

/// <summary>
/// 超时任务实例自动处理
/// by 贾世义 2011-07-01
/// </summary>
public class TimerTaskTimeOut : MyQuery.Utils.TimerTask.ITimerTask
{
/// <summary>
/// 执行
/// </summary>
public void Run()
{

//任务执行逻辑

}

}

3、在系统启动时启动一个新线程调用定时任务 Global中实现

protected void Application_Start(object sender, EventArgs e)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~/") + @"\log4net.config"));
log4net.ILog logger = log4net.LogManager.GetLogger(this.GetType());
try
{
TimerInfo timerInfo = new TimerInfo();
timerInfo.Type = TimerTypes.EveryDay;
timerInfo.RunTime = Convert.ToDateTime("2000-01-01 18:00");
TimerTaskTimeOut task = new TimerTaskTimeOut();
Thread threadTask = TimerTaskService.CreateTimerTaskService(timerInfo, task);
threadTask.Start();
}
catch (Exception ex)
{
logger.Error("启动定时任务出错,已放弃", ex);
}
}

非常感谢jumbot的提醒,通过如下的方法可以避免Application_End
/// <summary>
/// 注册一缓存条目在5分钟内到期,到期后触发的调事件
/// </summary>
private void RegisterCacheEntry(string url)
{
HttpContext.Current.Cache.Add("TimerTaskNeedCache", url, null, DateTime.MaxValue,
TimeSpan.FromMinutes(5), System.Web.Caching.CacheItemPriority.NotRemovable,
new System.Web.Caching.CacheItemRemovedCallback(CacheItemRemovedCallback));
}

/// <summary>
/// 缓存项过期时程序模拟点击页面,阻止应用程序结束
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="reason"></param>
private void CacheItemRemovedCallback(string key, object value, System.Web.Caching.CacheItemRemovedReason reason)
{
System.Net.WebClient client = new System.Net.WebClient();
client.DownloadData("http://" + value.ToString() + "/Default.aspx");
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Cache["TimerTaskNeedCache"] == null)
{
//缓存页面
string url = HttpContext.Current.Request.Url.Host;
if (HttpContext.Current.Request.Url.Port != 80)
{
url += ":" + HttpContext.Current.Request.Url.Port;
}
RegisterCacheEntry(url);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值