工作中, 我们常常需要开发windows服务, 那么, 一个可维护性好, 可扩展性高的的windows程序可以使我们省去不少的时间和精力.
我们来分析一下
一个windows服务应该看成是一个对象, 它拥有以下基本行为
行为: 执行行为.(这个服务要做什么事)
同一种行为, 不同的实现逻辑, 典型的工厂模式.
下面, 我们来定义两个windows服务类
public class OneTask : IWindowTask{public void Run(params object[] parms){Console.WriteLine("我是第一个window模拟服务.第一第一");
}}public class TwoTask:IWindowTask{public void Run(params object[] parms) {Console.WriteLine("我是第二个window模拟服务.第二第二");
}}以及约束其行为的接口
public interface IWindowTask
{
void Run(params object[] parms);
}
工厂
public class TaskFactory{static Hashtable ht = Hashtable.Synchronized(new Hashtable());public static IWindowTask GetTask(string classPath, IList parms) {if (ht[classPath] != null)return (IWindowTask)ht[classPath];
else {
//var taskInstance = Activator.CreateInstance(Type.GetType(classPath));
//var taskInstance = System.Reflection.Assembly.Load("MyWindowServiceFramwork").CreateInstance(classPath);
object taskInstance=null;taskInstance = Type.GetType(classPath).GetConstructor(Type.EmptyTypes).Invoke(null);
ht[classPath] = taskInstance;return (IWindowTask)taskInstance;
}}public static IWindowTask GetTask(string classPath) {return GetTask(classPath, null);}}枚举
public enum InterValType {second=1,minute=2,hour=3,day=4,week=5,month=6}//给定时控件添加一个任务类ID的属性, 在下面要用到
class MyTime : System.Timers.Timer {
public int TaskID { get; set; }}private static void NewMethod1(){MyPractiseEntities enty = new MyPractiseEntities();
//获得所有的有效任务.
var tasks = enty.MyTask.Where(x => x.enable == true);
foreach (var item in tasks){MyTime mytime = new MyTime();
mytime.TaskID = item.ID;//将任务ID付给当前的定时类ID
mytime.Start(); //开始, 默认间隔是100毫秒
//达到时间间隔执行. 可以理解为每一个定时控件都是一个新的线程.
mytime.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e){//记录逻辑操作耗时多少, 用以计算下一次运行此方法的时间间隔.
System.Diagnostics.Stopwatch stop = new System.Diagnostics.Stopwatch();
stop.Start();MyPractiseEntities enty2 = new MyPractiseEntities();
var currentTimer = sender as MyTime;
//必须通过当前的时间控件重新获得数据库对象. 如果直接写item(见上一级的foreach), 那么得到的item始终是tasks集合的最后一个.
var currentitem = enty2.MyTask.Where(x => x.ID == currentTimer.TaskID).FirstOrDefault();//如果当前任务满足执行条件
if (currentitem.LastRunTime <= DateTime.Now && (currentitem.NextRunTime == null || currentitem.NextRunTime <= DateTime.Now)){currentTimer.Stop();//暂停当前任务
//填充当前任务的所有参数
var itemParameter = enty2.MyTaskParameter.Where(x => x.TaskID == currentitem.ID).ToList();Func<IList<MyTaskParameter>, object[]> toObjects=x=>{
object[] objs =new object[ x.Count];for (int i = 0; i < x.Count; i++){objs[i] = x[i].ParmValue;}return objs;
};//获得并执行
//使用工厂反射出需要执行的任务类,并转化为接口对象/
IWindowTask itask = TaskFactory.GetTask(currentitem.ClassPath);//执行
itask.Run(toObjects(itemParameter));System.Threading.Thread.Sleep(2000);//更新下一次执行的时间
Func<int, InterValType, double> plusSecond = (intervalue, intervalueType) =>{var temp = 0;switch ((int)intervalueType){case 1: temp = currentitem.Interval.Value; break;case 2: temp = currentitem.Interval.Value * 60; break;case 3: temp = currentitem.Interval.Value * 60 * 60; break;case 4: temp = currentitem.Interval.Value * 60 * 60 * 24; break;}return temp;
};//读取配置文件来获得时间间隔
var tempsecond = plusSecond(currentitem.Interval.Value, (InterValType)currentitem.IntervalType.Value);DateTime d1 = currentitem.NextRunTime.Value;currentitem.NextRunTime = d1.AddSeconds(tempsecond);currentitem.LastRunTime = DateTime.Now;enty2.SaveChanges();//更新任务的状态信息
stop.Stop();//监视停止
//时间控件下一次执行的时间间隔为配置间隔减去这次运行时长.
currentTimer.Interval = tempsecond * 1000 - stop.ElapsedMilliseconds;//开始时间控件
currentTimer.Start();Console.WriteLine(); Console.WriteLine();}};}}
程序下载: 见群共享搜索MyWIndowService