这篇主要配合数据使用

先说数据库

名字都很标准----------------------------------

------------------------------------------------------------------

贴代码

1.IScheduleTaskService-----------Task表的接口

    /// <summary>
/// Task service interface
/// </summary>
public partial interface IScheduleTaskService
{
/// <summary>
/// Deletes a task
/// </summary>
/// <param name="task">Task</param>
void DeleteTask(ScheduleTask task); /// <summary>
/// Gets a task
/// </summary>
/// <param name="taskId">Task identifier</param>
/// <returns>Task</returns>
ScheduleTask GetTaskById(int taskId); /// <summary>
/// Gets a task by its type
/// </summary>
/// <param name="type">Task type</param>
/// <returns>Task</returns>
ScheduleTask GetTaskByType(string type); /// <summary>
/// Gets all tasks
/// </summary>
/// <param name="showHidden">A value indicating whether to show hidden records</param>
/// <returns>Tasks</returns>
IList<ScheduleTask> GetAllTasks(bool showHidden = false); /// <summary>
/// Inserts a task
/// </summary>
/// <param name="task">Task</param>
void InsertTask(ScheduleTask task); /// <summary>
/// Updates the task
/// </summary>
/// <param name="task">Task</param>
void UpdateTask(ScheduleTask task);
}

2.ScheduleTaskService-------------Task表的实现

    /// <summary>
/// Task service
/// </summary>
public partial class ScheduleTaskService : IScheduleTaskService
{
#region Fields private readonly IRepository<ScheduleTask> _taskRepository; #endregion #region Ctor public ScheduleTaskService(IRepository<ScheduleTask> taskRepository)
{
this._taskRepository = taskRepository;
} #endregion #region Methods /// <summary>
/// Deletes a task
/// </summary>
/// <param name="task">Task</param>
public virtual void DeleteTask(ScheduleTask task)
{
if (task == null)
throw new ArgumentNullException("task"); _taskRepository.Delete(task);
} /// <summary>
/// Gets a task
/// </summary>
/// <param name="taskId">Task identifier</param>
/// <returns>Task</returns>
public virtual ScheduleTask GetTaskById(int taskId)
{
if (taskId == )
return null; return _taskRepository.GetById(taskId);
} /// <summary>
/// Gets a task by its type
/// </summary>
/// <param name="type">Task type</param>
/// <returns>Task</returns>
public virtual ScheduleTask GetTaskByType(string type)
{
if (String.IsNullOrWhiteSpace(type))
return null; var query = _taskRepository.Table;
query = query.Where(st => st.Type == type);
query = query.OrderByDescending(t => t.Id); var task = query.FirstOrDefault();
return task;
} /// <summary>
/// Gets all tasks
/// </summary>
/// <param name="showHidden">A value indicating whether to show hidden records</param>
/// <returns>Tasks</returns>
public virtual IList<ScheduleTask> GetAllTasks(bool showHidden = false)
{
var query = _taskRepository.Table;
if (!showHidden)
{
query = query.Where(t => t.Enabled);
}
query = query.OrderByDescending(t => t.Seconds); var tasks = query.ToList();
return tasks;
} /// <summary>
/// Inserts a task
/// </summary>
/// <param name="task">Task</param>
public virtual void InsertTask(ScheduleTask task)
{
if (task == null)
throw new ArgumentNullException("task"); _taskRepository.Insert(task);
} /// <summary>
/// Updates the task
/// </summary>
/// <param name="task">Task</param>
public virtual void UpdateTask(ScheduleTask task)
{
if (task == null)
throw new ArgumentNullException("task"); _taskRepository.Update(task);
} #endregion
}

IRepository--------后续写数据库相关的时候再连着EF一起说------------------------

3.ScheduleTask---------------------实体类

    /// <summary>
/// Schedule task
/// </summary>
public partial class ScheduleTask : BaseEntity
{
/// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the run period (in seconds)
/// </summary>
public int Seconds { get; set; } /// <summary>
/// Gets or sets the type of appropriate ITask class
/// </summary>
public string Type { get; set; } /// <summary>
/// Gets or sets the value indicating whether a task is enabled
/// </summary>
public bool Enabled { get; set; } /// <summary>
/// Gets or sets the value indicating whether a task should be stopped on some error
/// </summary>
public bool StopOnError { get; set; } /// <summary>
/// Gets or sets the machine name (instance) that leased this task. It's used when running in web farm (ensure that a task in run only on one machine). It could be null when not running in web farm.
/// </summary>
public string LeasedByMachineName { get; set; }
/// <summary>
/// Gets or sets the datetime until the task is leased by some machine (instance). It's used when running in web farm (ensure that a task in run only on one machine).
/// </summary>
public DateTime? LeasedUntilUtc { get; set; } /// <summary>
/// Gets or sets the datetime when it was started last time
/// </summary>
public DateTime? LastStartUtc { get; set; }
/// <summary>
/// Gets or sets the datetime when it was finished last time (no matter failed ir success)
/// </summary>
public DateTime? LastEndUtc { get; set; }
/// <summary>
/// Gets or sets the datetime when it was sucessfully finished last time
/// </summary>
public DateTime? LastSuccessUtc { get; set; }
}

4.BaseEntity------------------------实体类,基类,写的很有意思

    /// <summary>
/// Base class for entities
/// </summary>
public abstract partial class BaseEntity
{
/// <summary>
/// Gets or sets the entity identifier
/// </summary>
public int Id { get; set; } public override bool Equals(object obj)
{
return Equals(obj as BaseEntity);
} private static bool IsTransient(BaseEntity obj)
{
return obj != null && Equals(obj.Id, default(int));
} private Type GetUnproxiedType()
{
return GetType();
} public virtual bool Equals(BaseEntity other)
{
if (other == null)
return false; if (ReferenceEquals(this, other))
return true; if (!IsTransient(this) &&
!IsTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
} return false;
} public override int GetHashCode()
{
if (Equals(Id, default(int)))
return base.GetHashCode();
return Id.GetHashCode();
} public static bool operator ==(BaseEntity x, BaseEntity y)
{
return Equals(x, y);
} public static bool operator !=(BaseEntity x, BaseEntity y)
{
return !(x == y);
}
}

5.Mapping映射

    public partial class ScheduleTaskMap : EntityTypeConfiguration<ScheduleTask>
{
public ScheduleTaskMap()
{
this.ToTable("ScheduleTask");
this.HasKey(t => t.Id);
this.Property(t => t.Name).IsRequired();
this.Property(t => t.Type).IsRequired();
}
}

-----------------至此操作上面scheduletask表的方法实体类都写完了-----------------------------------

6.ITask-----自动任务执行继承这个接口就可以了

    /// <summary>
/// Interface that should be implemented by each task
/// </summary>
public partial interface ITask
{
/// <summary>
/// Executes a task
/// </summary>
void Execute();
}

7.Task

    /// <summary>
/// Task
/// </summary>
public partial class Task
{
#region Ctor /// <summary>
/// Ctor for Task
/// </summary>
private Task()
{
this.Enabled = true;
} /// <summary>
/// Ctor for Task
/// </summary>
/// <param name="task">Task </param>
public Task(ScheduleTask task)
{
this.Type = task.Type;
this.Enabled = task.Enabled;
this.StopOnError = task.StopOnError;
this.Name = task.Name;
} #endregion #region Utilities private ITask CreateTask(ILifetimeScope scope)
{
ITask task = null;
if (this.Enabled)
{
var type2 = System.Type.GetType(this.Type);
if (type2 != null)
{
object instance;
if (!EngineContext.Current.ContainerManager.TryResolve(type2, scope, out instance))
{
//not resolved
instance = EngineContext.Current.ContainerManager.ResolveUnregistered(type2, scope);
}
task = instance as ITask;
}
}
return task;
} #endregion #region Methods /// <summary>
/// Executes the task
/// </summary>
/// <param name="throwException">A value indicating whether exception should be thrown if some error happens</param>
/// <param name="dispose">A value indicating whether all instances should be disposed after task run</param>
/// <param name="ensureRunOnOneWebFarmInstance">A value indicating whether we should ensure this task is run on one farm node at a time</param>
public void Execute(bool throwException = false, bool dispose = true, bool ensureRunOnOneWebFarmInstance = true)
{
//background tasks has an issue with Autofac
//because scope is generated each time it's requested
//that's why we get one single scope here
//this way we can also dispose resources once a task is completed
var scope = EngineContext.Current.ContainerManager.Scope();
var scheduleTaskService = EngineContext.Current.ContainerManager.Resolve<IScheduleTaskService>("", scope);
var scheduleTask = scheduleTaskService.GetTaskByType(this.Type); try
{
//task is run on one farm node at a time?
if (ensureRunOnOneWebFarmInstance)
{
//is web farm enabled (multiple instances)?
var nopConfig = EngineContext.Current.ContainerManager.Resolve<NopConfig>("", scope);
if (nopConfig.MultipleInstancesEnabled)
{
var machineNameProvider = EngineContext.Current.ContainerManager.Resolve<IMachineNameProvider>("", scope);
var machineName = machineNameProvider.GetMachineName();
if (String.IsNullOrEmpty(machineName))
{
throw new Exception("Machine name cannot be detected. You cannot run in web farm.");
//actually in this case we can generate some unique string (e.g. Guid) and store it in some "static" (!!!) variable
//then it can be used as a machine name
} //lease can't be aquired only if for a different machine and it has not expired
if (scheduleTask.LeasedUntilUtc.HasValue &&
scheduleTask.LeasedUntilUtc.Value >= DateTime.UtcNow &&
scheduleTask.LeasedByMachineName != machineName)
return; //lease the task. so it's run on one farm node at a time
scheduleTask.LeasedByMachineName = machineName;
scheduleTask.LeasedUntilUtc = DateTime.UtcNow.AddMinutes();
scheduleTaskService.UpdateTask(scheduleTask);
}
} //initialize and execute
var task = this.CreateTask(scope);
if (task != null)
{
this.LastStartUtc = DateTime.UtcNow;
if (scheduleTask != null)
{
//update appropriate datetime properties
scheduleTask.LastStartUtc = this.LastStartUtc;
scheduleTaskService.UpdateTask(scheduleTask);
}
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.ContainerManager.Resolve<ILogger>("", scope);
logger.Error(string.Format("Error while running the '{0}' schedule task. {1}", this.Name, exc.Message), exc);
if (throwException)
throw;
} if (scheduleTask != null)
{
//update appropriate datetime properties
scheduleTask.LastEndUtc = this.LastEndUtc;
scheduleTask.LastSuccessUtc = this.LastSuccessUtc;
scheduleTaskService.UpdateTask(scheduleTask);
} //dispose all resources
if (dispose)
{
scope.Dispose();
}
} #endregion #region Properties /// <summary>
/// Datetime of the last start
/// </summary>
public DateTime? LastStartUtc { get; private set; } /// <summary>
/// Datetime of the last end
/// </summary>
public DateTime? LastEndUtc { get; private set; } /// <summary>
/// Datetime of the last success
/// </summary>
public DateTime? LastSuccessUtc { get; private set; } /// <summary>
/// A value indicating type of the task
/// </summary>
public string Type { get; private set; } /// <summary>
/// A value indicating whether to stop task on error
/// </summary>
public bool StopOnError { get; private set; } /// <summary>
/// Get the task name
/// </summary>
public string Name { get; private set; } /// <summary>
/// A value indicating whether the task is enabled
/// </summary>
public bool Enabled { get; set; } #endregion
}

8.TaskManager

    /// <summary>
/// Represents task manager
/// </summary>
public partial class TaskManager
{
private static readonly TaskManager _taskManager = new TaskManager();
private readonly List<TaskThread> _taskThreads = new List<TaskThread>();
private const int _notRunTasksInterval = * ; //30 minutes private TaskManager()
{
} /// <summary>
/// Initializes the task manager
/// </summary>
public void Initialize()
{
this._taskThreads.Clear(); var taskService = EngineContext.Current.Resolve<IScheduleTaskService>();
var scheduleTasks = taskService
.GetAllTasks()
.OrderBy(x => x.Seconds)
.ToList(); //group by threads with the same seconds
foreach (var scheduleTaskGrouped in scheduleTasks.GroupBy(x => x.Seconds))
{
//create a thread
var taskThread = new TaskThread
{
Seconds = scheduleTaskGrouped.Key
};
foreach (var scheduleTask in scheduleTaskGrouped)
{
var task = new Task(scheduleTask);
taskThread.AddTask(task);
}
this._taskThreads.Add(taskThread);
} //sometimes a task period could be set to several hours (or even days).
//in this case a probability that it'll be run is quite small (an application could be restarted)
//we should manually run the tasks which weren't run for a long time
var notRunTasks = scheduleTasks
//find tasks with "run period" more than 30 minutes
.Where(x => x.Seconds >= _notRunTasksInterval)
.Where(x => !x.LastStartUtc.HasValue || x.LastStartUtc.Value.AddSeconds(x.Seconds) < DateTime.UtcNow)
.ToList();
//create a thread for the tasks which weren't run for a long time
if (notRunTasks.Any())
{
var taskThread = new TaskThread
{
RunOnlyOnce = true,
Seconds = * //let's run such tasks in 5 minutes after application start
};
foreach (var scheduleTask in notRunTasks)
{
var task = new Task(scheduleTask);
taskThread.AddTask(task);
}
this._taskThreads.Add(taskThread);
}
} /// <summary>
/// Starts the task manager
/// </summary>
public void Start()
{
foreach (var taskThread in this._taskThreads)
{
taskThread.InitTimer();
}
} /// <summary>
/// Stops the task manager
/// </summary>
public void Stop()
{
foreach (var taskThread in this._taskThreads)
{
taskThread.Dispose();
}
} /// <summary>
/// Gets the task mamanger instance
/// </summary>
public static TaskManager Instance
{
get
{
return _taskManager;
}
} /// <summary>
/// Gets a list of task threads of this task manager
/// </summary>
public IList<TaskThread> TaskThreads
{
get
{
return new ReadOnlyCollection<TaskThread>(this._taskThreads);
}
}
}

9.TaskThread

    /// <summary>
/// Represents task thread
/// </summary>
public partial class TaskThread : IDisposable
{
private Timer _timer;
private bool _disposed;
private readonly Dictionary<string, Task> _tasks; internal TaskThread()
{
this._tasks = new Dictionary<string, Task>();
this.Seconds = * ;
} private void Run()
{
if (Seconds <= )
return; this.StartedUtc = DateTime.UtcNow;
this.IsRunning = true;
foreach (Task task in this._tasks.Values)
{
task.Execute();
}
this.IsRunning = false;
} private void TimerHandler(object state)
{
this._timer.Change(-, -);
this.Run();
if (this.RunOnlyOnce)
{
this.Dispose();
}
else
{
this._timer.Change(this.Interval, this.Interval);
}
} /// <summary>
/// Disposes the instance
/// </summary>
public void Dispose()
{
if ((this._timer != null) && !this._disposed)
{
lock (this)
{
this._timer.Dispose();
this._timer = null;
this._disposed = true;
}
}
} /// <summary>
/// Inits a timer
/// </summary>
public void InitTimer()
{
if (this._timer == null)
{
this._timer = new Timer(new TimerCallback(this.TimerHandler), null, this.Interval, this.Interval);
}
} /// <summary>
/// Adds a task to the thread
/// </summary>
/// <param name="task">The task to be added</param>
public void AddTask(Task task)
{
if (!this._tasks.ContainsKey(task.Name))
{
this._tasks.Add(task.Name, task);
}
} /// <summary>
/// Gets or sets the interval in seconds at which to run the tasks
/// </summary>
public int Seconds { get; set; } /// <summary>
/// Get or sets a datetime when thread has been started
/// </summary>
public DateTime StartedUtc { get; private set; } /// <summary>
/// Get or sets a value indicating whether thread is running
/// </summary>
public bool IsRunning { get; private set; } /// <summary>
/// Get a list of tasks
/// </summary>
public IList<Task> Tasks
{
get
{
var list = new List<Task>();
foreach (var task in this._tasks.Values)
{
list.Add(task);
}
return new ReadOnlyCollection<Task>(list);
}
} /// <summary>
/// Gets the interval at which to run the tasks
/// </summary>
public int Interval
{
get
{
return this.Seconds * ;
}
} /// <summary>
/// Gets or sets a value indicating whether the thread whould be run only once (per appliction start)
/// </summary>
public bool RunOnlyOnce { get; set; }
}

-------------------------

10.Global.ascx.cs

        protected void Application_Start()
{
TaskManager.Instance.Initialize();
TaskManager.Instance.Start();
}

使用

CancelOrderTask-----------路径:BotanicSystem.Services.Order.CancelOrderTask,BotanicSystem.Services

贴一条数据库数据

3 订单自动取消 1000 BotanicSystem.Services.Order.CancelOrderTask,BotanicSystem.Services False False NULL NULL 2016-10-13 00:54:31.927 NULL NULL

贴代码

    public partial class CancelOrderTask:ITask
{
#region fields private readonly IOrderInfoService _orderInfoService;
#endregion #region Ctor public CancelOrderTask(IOrderInfoService orderInfoService)
{
_orderInfoService = orderInfoService;
} #endregion
public void Execute()
{
//获取所有30分钟内未支付的订单
var cancelOrders = _orderInfoService.GetListByWhere(
p =>
DbFunctions.DiffMinutes(p.Add_Time, DateTime.Now) >= &&
(p.Status == (int) OrderStatus.未提交) || p.Status == (int) OrderStatus.进行中); //设置订单状态为取消
foreach (var order in cancelOrders)
{
order.Status = (int) OrderStatus.已过期;
}
_orderInfoService.UpdateOrders(cancelOrders);
}
}

自动执行任务管理---TaskManage的更多相关文章

  1. WPF:自动执行"机器人"程序若干注意事项

    企业应用中,经常会遇到一些需要定时自动执行的程序来完成某些功能,比如:自动定时从第三方web service取回数据.定时对历史数据进行清理.定时向ftp上传业务数据... 这类程序,我习惯称为“机器 ...

  2. 使用php作linux自动执行脚本

    使用php作linux自动执行脚本 [来源] 达内    [编辑] 达内   [时间]2013-03-21 在作社区时, 时常需要统计上线人数等数据. 一般做法是, 把这段代码放在用户 login或者 ...

  3. (转)在网页中JS函数自动执行常用三种方法

    原文:http://blog.sina.com.cn/s/blog_6f6b4c3c0100nxx8.html 在网页中JS函数自动执行常用三种方法 在网页中JS函数自动执行常用三种方法 在HTML中 ...

  4. jQuery在HTML文档加载完毕后自动执行某个事件;

    原来onchange=“fucntionname(parms)”: <select name="country" id="selCountries_{$sn}&qu ...

  5. linux系统自动执行任务(转)

    开机启动 开机启动应该是我们很经常的需求了,我们常需要在开机时就自动执行某些命令来开启服务,进程等,有了它我们不必再在每次开机时输入同一堆命令. chkconfig命令 使用chkconfig命令可以 ...

  6. JS函数自动执行

    关于让网页中的JavaScript函数自动执行,方法就多洛,但是万变不离其宗,下面给大家介绍一下! 前提条件,网页中必须有JS函数代码,或者,使用文件导入的方法也行: 在HTML中的Head区域中,有 ...

  7. Oracle自动执行任务(存储过程)

    Oracle自动执行任务(存储过程) SQL> variable job number;SQL> begin2 dbms_job.submit(:job,'存储过程名;',sysdate, ...

  8. 使用自定义脚本扩展程序自动执行 VM 自定义任务

     在 Build 开发者大会上推出VM 扩展程序的其中一个称为"自定义脚本扩展程序",它支持 PowerShell.如果这是您第一次访问这些博客,可能需要查看以前的博客,请单击 ...

  9. 转 Windows 7设置定时自动执行任务方法

    在使用电脑的时候可能会遇到一些需要无人值守让电脑自行执行任务后定时关机的情形,在Win7系统中,我们可以使用"任务计划"设置功能结合 shutdown命令灵活设置任务计划,让Win ...

随机推荐

  1. gdbsever 使用说明

    gdbsever 使用说明 在新塘N3292x平台下 编译 gdbsever ./configure --target=arm-linux --host=arm-linux arm-linux-gdb ...

  2. mysql连结查询

    2016年4月13日 18:08:22 星期三 union 会生成临时表, 然后一同取出合并 join 或子查询, 会生成临时表进行嵌套循环 临时表, 缺点就是没有索引

  3. VIM插件攻略

    工欲善其事,必先利其器.一个强大的开发环境可以大大提高工作效率.好吧,我知道这是废话...不过,我想一定有很多跟我一样打算进入Linux平台开发的新手,一开始都为找不到一个像Windows下的VS那样 ...

  4. Vim 键盘指令高清图

    个人感觉挺好用的 推荐大家使用windows版的vim,个人用着感觉不错,在linux上用惯了vim的朋友可以试试这个.

  5. python中datetime模块

    Python提供了多个内置模块用于操作日期时间,像calendar,time,datetime.time模块我在之前的文章已经有所介绍,它提供 的接口与C标准库time.h基本一致.相比于time模块 ...

  6. Pyqt 获取动态生成的QLineEdit值

    动态生成控件参考上一篇: http://www.cnblogs.com/dcb3688/p/4588814.html 那如何获取动态生成控件的值呢? 比如,动态的生成10个输入框QLineEdit,输 ...

  7. iframe无刷新跨域并获得返回值

    参考:http://geeksun.iteye.com/blog/1070607 /** * iframe跨域提交大数据 * @param action 跨域地址 * @param arr [ {na ...

  8. SQL Server 2012 新增语法

    --连接两个字符串. CONCAT(TelePhone,UserName,' : ',LoginVCode) FROM [dbo].[TB_NUsers] --SQL Server2012新增了两个逻 ...

  9. html学习第一天笔记——第六章节

    <input type="reset" value="重置"> 使用重置按钮,重置表单信息<input type="submit&q ...

  10. iOS @@创建NSURL的字面量

    @@ 是创建 NSURL 的字面量的绝佳方法(例如:@@"http://example.com")