nopcommerce计划任务分析

2012-06-19

对比了一下nopcommerce和orchard的计划任务,orchard的复杂的不是一点点,如果想拆下来自己用难度很大,搜索拆了orchard的lucene处理模块,邮件队列拆的discuznt和nopcommerce的结合,计划任务就拆nopcommerce的了,discuznt计划任务设计的没nopcommerce的好。

1.nopcommerce的tasks结构如下:

IScheduleTaskService.cs 接口,这个主要是获取数据库里的任务信息,ScheduleTaskService.cs去实现它就可以了,当然需要在容器里注入一下。

ITask 这个接口比较特别但是很重要,所有的任务处理类都要实现里面唯一的Execute方法。执行计划任务时就需要通过反射来执行这个实现。

namespace Nop.Services.Tasks { /// <summary>
    /// Interface that should be implemented by each task /// </summary>
    public partial interface ITask { /// <summary>
        /// Execute task /// </summary>
        void Execute(); } }

核心类之一:Task.cs,这个主要是处理任务的执行过程及执行过程类的结果处理。

private ITask CreateTask() { ITask task = null; if (this.Enabled) { var type2 = System.Type.GetType(this._type); if (type2 != null) { task = Activator.CreateInstance(type2) as ITask; } //this._enabled = task != null;
 } return task; }

通过反射来找到编写的计划任务类。例如发送邮件的任务。

执行完任务后需要将数据库里的任务记录状态更改,主要是时间状态变更。

核心执行方法:

        /// <summary>
        /// 执行任务 /// </summary>
        public void Execute() { this._isRunning = true; try { var task = this.CreateTask(); if (task != null) { this._lastStartUtc = DateTime.UtcNow; task.Execute(); this._lastEndUtc = this._lastSuccessUtc = DateTime.UtcNow; } } catch (Exception exc) { this._enabled = !this.StopOnError; this._lastEndUtc = DateTime.UtcNow; //log error
                var logger = EngineContext.Current.Resolve<ILogger>(); logger.Error(string.Format("Error while running the '{0}' schedule task. {1}", this._name, exc.Message), exc); } try { //find current schedule task
                var scheduleTaskService = EngineContext.Current.Resolve<IScheduleTaskService>(); var scheduleTask = scheduleTaskService.GetTaskByType(this._type); if (scheduleTask != null) { scheduleTask.LastStartUtc = this.LastStartUtc; scheduleTask.LastEndUtc = this.LastEndUtc; scheduleTask.LastSuccessUtc = this.LastSuccessUtc; scheduleTaskService.UpdateTask(scheduleTask); } } catch (Exception exc) { Debug.WriteLine(string.Format("Error saving schedule task datetimes. Exception: {0}", exc)); } this._isRunning = false; }

 任务管理类:TaskManager.cs,主要负责任务的初始化,添加到线程列表,任务的开始和停止。需要在Global里初始化和开始任务,它会根据线程里的定时器自动读取任务列表执行任务。

            //开始执行任务
            if (databaseInstalled) { TaskManager.Instance.Initialize(); TaskManager.Instance.Start(); }

任务线程管理类:TaskThread.cs,任务线程类,TaskManager将任务都添加到此线程管理类里,此线程管理主要负责判断任务的执行状态,线程执行间隔时间及调用任务执行的主方法Execute,通过Timer定时器实现定时自动运行。

主方法为:

        private void Run() { if (_seconds <=0) return; this._startedUtc = DateTime.UtcNow; this._isRunning = true; foreach (Task task in this._tasks.Values) { task.Execute(); } this._isRunning = false; }

从任务列表中读取任务并执行。

以上是简单的分析,目前只是拿来主义,在学习和整理的同时加深一下对开源代码的理解。

作者:robotbird, 分类:关于代码 标签: a donet , 浏览(5890), 评论(0)
上一篇: 最简洁全选js代码
下一篇: 从今天开始坚持不刷技术类文章

相关文章

(0)条评论 订阅

发表评论

电子邮件用于回复通知和avatar全球唯一头像 *

*