首页 > 其他分享 >WEB后台定时任务服务类及实现 源代码

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

时间:2022-11-18 19:32:54浏览次数:50  
标签:WEB 源代码 timerInfo Value DateTime new 类及 定时 now


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

实现思路:

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);
            }
        }

标签:WEB,源代码,timerInfo,Value,DateTime,new,类及,定时,now
From: https://blog.51cto.com/u_14751752/5869210

相关文章

  • 架构之反射实现源代码(不知道要干什么确需要知道能干什么)
    做过架构的朋友或许都有过不知道开发人员要干什么确需要知道开发人员能干什么的困惑,估计大家的解决思路应该也会往一处想-反射介绍下自己的实现思路和代码:1、定义接口如:  ......
  • 8. 使Web工程依赖于Java工程
    #在pro02-maven-web工程的pom.xml文件下,添加对pro01-maven-java工程的依赖:(通过坐标) #添加测试代码:##在pro02-maven-web工程的src目录下,添加文件夹:test/java/com/at......
  • WebGL Debugging and Profiling Tools(调试和分析工具)
    by PatrickCozzi,whoworksonthe Cesium WebGLengine.WiththenewshadereditorinFirefox27(availablenowin Aurora),WebGLtoolsaretakingabigst......
  • 7. Maven创建web工程
    #命令行转到D:\Maven\maven-workspace工作空间,执行如下代码:mvnarchetype:generate-DarchetypeGroupId=org.apache.maven.archetypes-DarchetypeArtifactId=maven-arch......
  • web应用程序
    二、web应用程序1、前言web开发:静态webhtml,css提供给所有人看的数据不会发生变化的动态web现在几乎所有的网站都是是动态提供给所有人的数据都是......
  • 项目开源 | 基于开源WebGIS的国内疫情数据可视化平台
    一、项目介绍本项目使用的技术是vite+Vue3,使用ArcGISAPIforjs前端地图开源框架,接口数据来源weibo。主要是对国内的疫情数据进行实时图表可视化。2022.11.12-2022.11.......
  • JavaWeb-06-Servlet
    6.Servlet6.1Servlet简介Servlet就是sun公司开发动态web的一门技术Sun公司在这些API中提供了一个接口叫作:Servlet,如果要开发一个Servlet程序,只需要完成两个步骤:编......
  • 构建反应式堆栈 Web 应用程序的支持
    版本6.0.0文档的这一部分涵盖了对构建的反应式堆栈Web应用程序的支持在反应式流​API上以在非阻塞上运行服务器,如Netty、Undertow和Servlet容器。各章节封面 Spr......
  • SQLSERVER调用WebAPI和WebService
    原文:https://blog.csdn.net/qq243348167/article/details/124243810第一步需开启组件开启组件sp_configure'showadvancedoptions',1;GORECONFIGURE;GOsp_confi......
  • 直播系统源代码,jquery实现百分比长度条
    直播系统源代码,jquery实现百分比长度条代码: jQuery部分  $("#provinceTop10List").click(function(){        PainmingTable(obj.provinceTop10......