一个简单易用的asp.net mvc 定时任务
因为项目中需要每月/每天建表,每天进行一些统计,所以封装了一个类库进行使用。
一、使用说明:
1. 把要执行的任务新建一个类放到本Web项目中,可以放在任意位置,建议放在AutoTask 文件夹下 2. 对该类应用属性 AutoTask 如下所示 [AutoTask(EnterMethod = "StartTask", IntervalSeconds = 86400, StartTime = "2016-12-28 00:00:00")] 说明:EnterMethod 是任务入口,IntervalSeconds 是执行间隔,StartTime 是开始执行时间 如果设置IntervalSeconds 为空或0 ,则该任务只启动时执行一次,忽略后面的start Time 参数 如果没有设置StartTime ,则该任务启动时立刻开始执行,按照间隔时间,每隔IntervalSeconds 秒执行一次。 如果StartTime 大于当前日期,则任务从StartTime 开始执行。 如果StartTime 小于当前日期,则从 StartTime + IntervalSecondes*n 开始执行,n为使该表达式大于DateTime.Now 的最小值。 3. 由此可以实现所有的定时功能。 如指定 每小时执行,则设置IntervalSeconds=3600,每天执行则设置IntervalSeconds=86400 若设置每天 0 点执行,则可以设置StartTime = "xxxx-xx-xx 00:00:00",IntervalSeconds=86400 若设置每周二晚上23 点执行 ,则可以设置StartTime = "xxxx-xx-xx 23:00:00",IntervalSeconds=604800 //86400*7 ,xxxx-xx-xx 可以设置为以前一个周二的日期 若设置每月,每年指定日期,则可以设置每天执行,然后在执行的代码里进行判断,判断日期是否是指定的日期,为保证易用性,本类库不进行扩展
二、源码说明:
1. 在Global.asax.cs Application_Start中添加如下代码
AutoTaskAttribute.RegisterTask();
添加Application_End 方法,解决IIS应用程序池自动回收的问题
1 2 3 4 5 6 7 8 9 10 | protected void Application_End( object sender, EventArgs e) { //下面的代码是关键,可解决IIS应用程序池自动回收的问题 Thread.Sleep(1000); //这里设置你的web地址,可以随便指向你的任意一个aspx页面甚至不存在的页面,目的是要激发Application_Start <br> //我这里是一个验证token的地址。 string url = System.Configuration.ConfigurationManager.AppSettings[ "tokenurl" ]; HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); Stream receiveStream = myHttpWebResponse.GetResponseStream(); //得到回写的字节流 } |
2. 把该类文件添加到项目中
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Web; using WebMVC.Utils; namespace WebMVC.Filters { /// <summary> /// Author:BigLiang(lmw) /// Date:2016-12-29 /// </summary> [AttributeUsage(AttributeTargets.Class)] public class AutoTaskAttribute : Attribute { /// <summary> /// 入口程序 /// </summary> public string EnterMethod { get; set; } /// <summary> /// 执行间隔秒数(未设置或0 则只执行一次) /// </summary> public int IntervalSeconds { get; set; } /// <summary> /// 开始执行日期 /// </summary> public string StartTime { get; set; } //保留对Timer 的引用,避免回收 private static Dictionary<AutoTaskAttribute, System.Threading.Timer> timers = new Dictionary<AutoTaskAttribute, System.Threading.Timer>(); /// <summary> /// Global.asax.cs 中调用 /// </summary> public static void RegisterTask() { new Task(() => StartAutoTask()).Start(); } /// <summary> /// 启动定时任务 /// </summary> private static void StartAutoTask() { var types = Assembly.GetExecutingAssembly().ExportedTypes.Where(t => Attribute.IsDefined(t, typeof(AutoTaskAttribute))).ToList(); foreach (var t in types) { try { var att = (AutoTaskAttribute)Attribute.GetCustomAttribute(t, typeof(AutoTaskAttribute)); if (att != null) { if (string.IsNullOrWhiteSpace(att.EnterMethod)) { throw new Exception("未指定任务入口!EnterMethod"); } var ins = Activator.CreateInstance(t); var method = t.GetMethod(att.EnterMethod); if (att.IntervalSeconds > 0) { int duetime = 0; //计算延时时间 if (string.IsNullOrWhiteSpace(att.StartTime)) { duetime = 1000; } else { var datetime = DateTime.Parse(att.StartTime); if (DateTime.Now <= datetime) { duetime = (int)(datetime - DateTime.Now).TotalSeconds * 1000; } else { duetime = att.IntervalSeconds * 1000 - ((int)(DateTime.Now - datetime).TotalMilliseconds) % (att.IntervalSeconds * 1000); } } timers.Add(att,new System.Threading.Timer((o) => { method.Invoke(ins, null); }, ins, duetime, att.IntervalSeconds * 1000)); } else { method.Invoke(ins, null); } } } catch (Exception ex) { //LogHelper.Error(t.FullName + " 任务启动失败", ex); } } } } }
3. 使用示例
/// <summary> /// 测试任务,每10分钟执行一次 /// </summary> [AutoTask(EnterMethod = "StartTask", IntervalSeconds = 600, StartTime = "2016-12-28 10:45:00")] public class TestTask { /// <summary> ////// </summary> public static void StartTask() { LogHelper.Info("定时任务启动成功!"); LogHelper.Info("定时任务执行完毕!"); } }
这是我的框架中关于定时任务的一块,以后会把整个框架分享出来。
简单就是美。
如果我的文章帮到了你,请告诉我,让我知道。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?