应用框架设计若干问题探讨之----计划任务

在开发企业应用中免不了有一些需要系统自动触发和处理的计划性任务,如果应用框架能有一个简单易用的任务机制,对减轻开发和设计人员的工作难度有极大的帮助。本章将致力于描述一个简单易用的任务机制。

1.1   需求分析

所谓计划任务,就是指在某个时点执行相应的处理。我们在.NET中自然的想到了System.Threading.Timer,它已经提供了一种定时器方式的执行某种任务的机制。但在企业应用中,它显得过于简单,我们需要它提供相应的扩展能力,特别是能定制触发策略。

1.2   详细设计

从设计角度,扩展Timer类是一个不错的想法;提供更加灵活的触发策略触发,给出一个简单易用的任务类。

1.2.1      ITriggerPolicy接口

    public interface ITriggerPolicy

    {

        /// <summary>

        /// 计算下一次触发时间。

        /// </summary>

        /// <remarks>

        /// 返回值为DateTime.MinValue时,策略关联的任务完成并从计划的执行队列删除。

        /// </remarks>

        /// <param name="triggerCount">策略被触发过的次数。</param>

        /// <param name="lastTime">触发相对时间。</param>

        /// <returns>返回下一次触发的时间。</returns>

        DateTime CalcNextTime(int triggerCount , DateTime lastTime);

    }

首先设计触发策略接口,给程序员自定义的机制,框架本身也实现了两个触发策略,一个基于定时器模式,一个基于日历模式。

更多模式需要自己定义。

 

1.2.2      Task

    /// <summary>

    /// 计划任务。

    /// </summary>

    public sealed class Task :IDisposable

    {

        #region Fields

 

        private TaskCallback _callback;

        private Object _stateObj;

        private ITriggerPolicy _policy;

        private int _maxCount;

 

        private IMutex _lock;

        private Timer _timer;

        private TaskState _state;

        private int _triggerCount;

        private int _currentPolicyTriggerCount;

        private DateTime _lastTriggerTime;

        private Exception _lastException;

 

        private Hashtable _properties = Hashtable.Synchronized(new Hashtable());

 

        #endregion

 

 

        #region Constructor(s)

 

        /// <summary>

        /// 用指定的策略初始化类 <see cref="Task"/> 的新实例。

        /// </summary>

        /// <param name="callback">任务回调委托。</param>

        /// <param name="policy">任务触发策略。</param>

        public Task(TaskCallback callback, ITriggerPolicy policy)

            :this(callback, null, policy)

        {

        }

 

        /// <summary>

        /// 用指定的策略和回调状态对象初始化类 <see cref="Task"/> 的新实例。

        /// </summary>

        /// <param name="callback">任务回调委托。</param>

        /// <param name="stateObj">回调状态对象。</param>

        /// <param name="policy">任务触发策略。</param>

        public Task(TaskCallback callback, Object stateObj, ITriggerPolicy policy)

            :this(callback, stateObj, policy, Int32.MaxValue)

        {

        }

 

        /// <summary>

        /// 用指定的策略、回调状态对象和最大执行次数初始化类 <see cref="Task"/> 的新实例。

        /// </summary>

        /// <param name="callback">任务回调委托。</param>

        /// <param name="stateObj">回调状态对象。</param>

        /// <param name="policy">任务触发策略。</param>

        /// <param name="maxCount">最大执行次数。</param>

        public Task(TaskCallback callback, Object stateObj, ITriggerPolicy policy, int maxCount)

        {

            Exceptions.ThrowIfNull(callback, "callback");

            Exceptions.ThrowIfNull(policy, "policy");

            Exceptions.ThrowIfNotPositive(maxCount, "maxCount");

 

            this._callback = callback;

            this._stateObj = stateObj;

            this._policy = policy;

            this._maxCount = maxCount;

 

            this._lock = new ThreadMutex();

            this._state = TaskState.Ready;

            this._triggerCount = 0;

            this._currentPolicyTriggerCount = 0;

            this._lastTriggerTime = DateTime.MinValue;

            this._lastException = null;

            this._timer = new Timer(new TimerCallback(Task.TimerProxy), this, -1, -1);

        }

 

        #endregion

 

        #region Properties

 

        /// <summary>

        /// 获取任务状态。

        /// </summary>

        public TaskState State

        {

            get

            {

                using (AutoReaderLock rlock = new AutoReaderLock(this._lock))

                {

                    return _state;

                }

            }

        }

 

        /// <summary>

        /// 获取任务被触发的次数。

        /// </summary>

        public int TriggerCount

        {

            get

            {

                using (AutoReaderLock rlock = new AutoReaderLock(this._lock))

                {

                    return _triggerCount;

                }

            }

        }

 

        /// <summary>

        /// 获取当前策略被触发的次数。

        /// </summary>

        public int CurrentPolicyTriggerCount

        {

            get

            {

                using (AutoReaderLock rlock = new AutoReaderLock(this._lock))

                {

                    return _currentPolicyTriggerCount;

                }

            }

        }

 

        /// <summary>

        /// 获取最后触发时间。

        /// 没有触发的任务为DateTime.MinValue

        /// </summary>

        public DateTime LastTriggerTime

        {

            get

            {

                using (AutoReaderLock rlock = new AutoReaderLock(this._lock))

                {

                    return _lastTriggerTime;

                }

            }

        }

 

        /// <summary>

        /// 获取最后一次触发的异常。

        /// </summary>

        public Exception LastException

        {

            get

            {

                using (AutoReaderLock rlock = new AutoReaderLock(this._lock))

                {

                    return _lastException;

                }

            }

        }

 

        /// <summary>

        /// 获取、设置任务的命名属性。

        /// </summary>

        /// <param name="name">属性名称。</param>

        /// <returns>属性值。</returns>

        public Object this[string name]

        {

            get

            {

                Exceptions.ThrowIfEmpty(name, "name");

                return this._properties[name];

            }

            set

            {

                Exceptions.ThrowIfEmpty(name, "name");

                this._properties[name] = value;

            }

        }

        #endregion

 

        #region Methods

 

        /// <summary>

        /// 启动任务。

        /// </summary>

        public void Startup()

        {

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                // 任务已经被处置

                if (this._state == TaskState.Disposed)

                    throw new ObjectDisposedException(SR.ObjectDisposed_Task);

 

                // 任务已经被启动

                if (this._state != TaskState.Ready)

                    return;

 

                this._state = TaskState.Scheduling;

 

                ChangeTimer();

 

                // 触发策略没有有效的触发时间,任务已经被处置

                if (this._state == TaskState.Disposed)

                    throw new ObjectDisposedException(SR.ObjectDisposed_Task);

            }

        }

 

        /// <summary>

        /// 停止任务。

        /// </summary>

        public void Shutdown()

        {

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                // 任务已经被处置

                if (this._state == TaskState.Disposed)

                    return;

 

                // 任务已经停止

                if (this._state == TaskState.Ready)

                    return;

 

                // 停止定时器

                this._timer.Change(-1, -1);

 

                this._state = TaskState.Ready;

            }

        }

 

        /// <summary>

        /// 修改任务触发策略。

        /// </summary>

        /// <param name="policy">触发策略。</param>

        public void Change(ITriggerPolicy policy)

        {

            Exceptions.ThrowIfNull(policy, "policy");

 

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                // 任务已经被处置

                if (this._state == TaskState.Disposed)

                    throw new ObjectDisposedException(SR.ObjectDisposed_Task);

 

                // 停止定时器

                this._timer.Change(-1, -1);

                this._policy = policy;

                this._currentPolicyTriggerCount = 0;

 

                // 如果当前状态不是就绪 , 修改定时器

                if (this._state != TaskState.Ready)

                {

                    ChangeTimer();

 

                    // 触发策略没有有效的触发时间,任务已经被处置

                    if (this._state == TaskState.Disposed)

                        throw new ObjectDisposedException(SR.ObjectDisposed_Task);

 

                }

            }

        }

 

        /// <summary>

        /// 任务对象传递给 <see cref="System.Threading.Timer"/> 的定时器回调委托。

        /// </summary>

        /// <param name="state">状态对象,它是 <see cref="Task"/>类的实例。</param>

        private static void TimerProxy(Object state)

        {

            Task task = (Task)state;

            Exception currException = null;

           

            // 执行前检测

            if (task.PreExecute())

            {

                try

                {

                    task._callback(task, task._stateObj);

                }

                catch (Exception e)

                {

                    currException = e;

                }

 

                // 执行后处理

                task.PostExecute(currException);

            }

        }

 

        // 执行前检测

        private bool PreExecute()

        {

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                // 任务已经被处置,不在执行

                if (this._state == TaskState.Disposed)

                    return false;

 

                // 修改状态以及相关执行计数

                this._state = TaskState.Executing;

                this._triggerCount++;

                this._currentPolicyTriggerCount++;

                this._lastTriggerTime = DateTime.Now;

            }

            return true;

        }

 

        // 执行后处理

        private void PostExecute(Exception e)

        {

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                // 任务已经被处置

                if (this._state == TaskState.Disposed)

                    return ;

 

                // 如果执行次数达到最大可执行次数,处置该任务

                if (this._maxCount == this._triggerCount)

                {

                    this.Dispose();

                    return;

                }

 

                // 记录最后异常

                if( e != null)

                    this._lastException = e;

 

                ChangeTimer();

 

                // 触发策略没有有效的触发时间,任务已经被处置

                if (this._state == TaskState.Disposed)

                    throw new ObjectDisposedException(SR.ObjectDisposed_Task);

 

                this._state = TaskState.Scheduling;

            }

        }

 

        private void ChangeTimer()

        {

            DateTime now = DateTime.Now;

            DateTime nextTime = this._policy.CalcNextTime(this._currentPolicyTriggerCount, now);

            if (nextTime < now)

            {

                this.Dispose();

                return;

            }

            int interval = (int)((nextTime - now).TotalMilliseconds);

            this._timer.Change(interval , -1);

        }

 

        #endregion

 

        #region IDisposable 成员

 

        /// <summary>

        /// 执行与释放或重置非托管资源相关的应用程序定义的任务。

        /// </summary>

        public void Dispose()

        {

            using (AutoWriterLock wlock = new AutoWriterLock(this._lock))

            {

                if (this._state == TaskState.Disposed)

                    return;

 

                this._timer.Change(-1, -1);

                this._timer.Dispose();

                this._state = TaskState.Disposed;

            }

 

            GC.SuppressFinalize(this);

        }

 

        #endregion

 

    }

}

Task类通过使用者提供的任务执行体和触发策略来调度任务。它封装了Timer类并提供了更多的业务元素:

Ø  提供了自定义触发策略机制

Ø  提供了一些应用级的属性

Ø  提供了一些应用自定义属性

1.3   应用实例

    class Program

    {

        static void Main(string[] args)

        {

            // 定义一个最初间隔10秒,后续间隔5秒执行的任务;并要求最多执行10

            Task task = new Task(TaskProc,null,

                new TimerTriggerPolicy(new TimeInterval(10),new TimeInterval(5)), 10);

            task["name"] = "First Task";

            task.Startup();

            Console.ReadLine();

            task.Dispose();

        }

 

        private static void TaskProc(Task task, Object state)

        {

            Console.WriteLine("任务:{0}", task["name"]);

            Console.WriteLine("/t执行次数 {0} , 执行时间 {1}", task.TriggerCount,DateTime.Now);

            // 当执行5次后,修改触发策略

            if (task.TriggerCount == 5)

                task.Change(new CalendarTriggerPolicy("0,15,30,45;*;*;*;*;1-5"));

        }

 }

使用任务类就像Timer类一样简单。

1.4   扩展话题

可能有很多需要继续扩展:

Ø  提供计划任务的管理类

Ø  提供计划任务数据库存储方案,并通过反射方式加载相应的执行体

Ø  提供计划任务编辑和维护的界面原型等等

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
辽B代驾管理系统对代驾订单管理、用户咨询管理、代驾订单评价管理、代驾订单投诉管理、字典管理、论坛管理、公告管理、新闻信息管理、司机管理、用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行辽B代驾管理系统程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。辽B代驾管理系统的开发让用户查看代驾订单信息变得容易,让管理员高效管理代驾订单信息。 辽B代驾管理系统具有管理员角色,用户角色,这几个操作权限。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看代驾订单,删除代驾订单操作,新增代驾订单操作,修改代驾订单操作。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。新闻管理页面,此页面提供给管理员的功能有:新增新闻,修改新闻,删除新闻。新闻类型管理页面,此页面提供给管理员的功能有:新增新闻类型,修改新闻类型,删除新闻类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值