现在的位置: 首页 > 综合 > 正文

[实践]开发扩展性良好的windows服务

2011年06月07日 ⁄ 综合 ⁄ 共 5525字 ⁄ 字号 评论关闭

工作中, 我们常常需要开发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);

    }

数据表image

添加两条记录image

工厂

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

抱歉!评论已关闭.