« 前一篇:ft了……
后一篇:GIF的透明处理 »

服务器端多线程任务调度程序的实现 @ 3/12/2004

技术类
这个东西还有很简单了,诸如ArrayList可以放进数据库、Scheduler终止的时候可以把ArrayList序列化到本地,在下次初始化的时候读出来、多个执行时间、多个Timer、ArrayList的插入/搜寻优化、等等诸如此类的方面都有很多改进余地。如果有谁在此基础上做了什么改进的话,烦请告知本人,在此深表感谢。

实现调度的类:
using System;

namespace ifyr.util {
    /// <summary>
    /// 多线程服务器端任务调度程序
    /// </summary>
    class Scheduler {
        //待处理事件列表
        static System.Collections.ArrayList alarmList = new System.Collections.ArrayList();
        //每10秒钟执行一次
        static System.Timers.Timer timer = new System.Timers.Timer(10 * 1000);

        //采用静态构造函数
        static Scheduler() {
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer);
            timer.Enabled = true;
        }

        //添加Alarm
        public static void AddAlarmEvent(Alarm alarm) {
            lock(alarmList) {
                alarmList.Add(alarm);
            }
            //如果timer没有运行,运行之。
            if(!timer.Enabled) {
                timer.Enabled = true;
            }
        }

        //计时器函数
        private static void OnTimer(Object source, System.Timers.ElapsedEventArgs e) {
            //防止重入,同时防止List被外面修改
            lock(alarmList) {
                //如果List为空,则停止Timer
                if(alarmList.Count == 0) {
                    timer.Enabled = false;
                }
                //如果List中有当前需要执行的任务,则执行并删除之
                for(int i=alarmList.Count-1; i >= 0; i--) {
                    Alarm alarm = (Alarm)alarmList[i];
                    if(DateTime.Now > alarm.AlarmTime) {
                        alarmList.RemoveAt(i);
                        alarm.Run();
                    }
                }
            }
        }
    }

    //注意此托管函数要求能够被独立执行,所以必须是static的函数
    //同时需要注意如果有同步的问题,需要在函数前面加上
    //[System.Runtime.CompilerServices.MethodImpl(
    // System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
    public delegate void AlarmEventHandler(object alarmEvent);

    /// <summary>
    /// 事件类
    /// </summary>
    public class Alarm {
        /// <summary>
        /// 事件类构造函数
        /// </summary>
        /// <param name="alarmEvent">待处理事件</param>
        /// <param name="alarmTime">触发时间</param>
        /// <param name="handler">处理函数</param>
        public Alarm(object alarmEvent, DateTime alarmTime, AlarmEventHandler handler) {
            this.alarmEvent = alarmEvent;
            this.alarmTime = alarmTime;
            this.AlarmHandler += handler;
            Scheduler.AddAlarmEvent(this);
        }

/* 04-03-17修改为线程池执行
        //多线程执行,立即返回
        public void Run() {
            new System.Threading.Thread(new System.Threading.ThreadStart(ActivateAlarm)).Start();
        }

        //因为ThreadStart委托不能给参数,所以作了这个函数是用来处理Alarm
        private void ActivateAlarm()    {
            AlarmHandler(alarmEvent);
        }
*/

        //线程池执行,立即返回
        public void Run() {
            System.Threading.ThreadPool.QueueUserWorkItem( new System.Threading.WaitCallback(AlarmHandler), alarmEvent);
        }

        /// <summary>
        /// 触发时间,只读。
        /// </summary>
        public DateTime AlarmTime {
            get{
                return alarmTime;
            }
        } private DateTime alarmTime;

        //待处理事件
        private object alarmEvent;
        //委托代理
        private event AlarmEventHandler AlarmHandler;
    }
}

使用方法示例:
应用程序:
using System;
using ifyr.util;
using System.IO;

namespace test {
    /// <summary>
    /// SchedulerTest 的摘要说明。
    /// </summary>
    public class SchedulerTest {
        public SchedulerTest() {
            DateTime now = DateTime.Now;
            for(int i=0; i < 20; i ++) {
                DateTime next = now.AddSeconds(i*5 + 3);
                new Alarm(next,next,new AlarmEventHandler(handle));
            }
        }

        [System.Runtime.CompilerServices.MethodImpl(
             System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
        public static void handle(object obj)  {
            System.IO.TextWriter writer=new System.IO.StreamWriter(@"F:\Test.txt",true);
            writer.WriteLine(obj + "\t\t" + DateTime.Now);
            writer.Close();
        }
    }
}

网页:
using System;
using System.Web;
using System.Runtime.CompilerServices;
using ifyr.util;

namespace test {
    public class Scheduler : System.Web.UI.Page {
        private void Page_Load(object sender, System.EventArgs e) {
            DateTime now = DateTime.Now;
            for(int i=0; i < 20; i ++) {
                DateTime next = now.AddSeconds(i*5 + 3);
                new Alarm(next,next,new AlarmEventHandler(handle));
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void handle(object obj)  {
            System.IO.TextWriter writer=new System.IO.StreamWriter(System.Web.HttpRuntime.AppDomainAppPath + "/test.txt",true);
            writer.WriteLine(obj + "\t\t" + DateTime.Now);
            writer.Close();
        }

        override protected void OnInit(EventArgs e) {
            InitializeComponent();
            base.OnInit(e);
        }
       
        private void InitializeComponent() {   
            this.Load += new System.EventHandler(this.Page_Load);
        }
    }
}
发布于 3/12/2004 3:16:25 | 评论:1
<匿名人士> @ 3/12/2004 9:16:11
GoOd

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1168
  • 评论数:2011